結果

問題 No.1084 積の積
ユーザー Haar
提出日時 2020-06-19 22:16:13
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 51 ms / 2,000 ms
コード長 5,368 bytes
コンパイル時間 2,012 ms
コンパイル使用メモリ 200,284 KB
最終ジャッジ日時 2025-01-11 06:44:05
ジャッジサーバーID
(参考情報)
judge3 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 5
other AC * 27
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include <bits/stdc++.h>
#ifdef DEBUG
#include <Mylib/Debug/debug.cpp>
#else
#define dump(...)
#endif
/**
* @title Modint
* @docs mint.md
*/
template <uint32_t M> class ModInt{
public:
constexpr static uint32_t MOD = M;
uint64_t val;
constexpr ModInt(): val(0){}
constexpr ModInt(int64_t n){
if(n >= M) val = n % M;
else if(n < 0) val = n % M + M;
else val = n;
}
inline constexpr auto operator+(const ModInt &a) const {return ModInt(val + a.val);}
inline constexpr auto operator-(const ModInt &a) const {return ModInt(val - a.val);}
inline constexpr auto operator*(const ModInt &a) const {return ModInt(val * a.val);}
inline constexpr auto operator/(const ModInt &a) const {return ModInt(val * a.inv().val);}
inline constexpr auto& operator=(const ModInt &a){val = a.val; return *this;}
inline constexpr auto& operator+=(const ModInt &a){if((val += a.val) >= M) val -= M; return *this;}
inline constexpr auto& operator-=(const ModInt &a){if(val < a.val) val += M; val -= a.val; return *this;}
inline constexpr auto& operator*=(const ModInt &a){(val *= a.val) %= M; return *this;}
inline constexpr auto& operator/=(const ModInt &a){(val *= a.inv().val) %= M; return *this;}
inline constexpr bool operator==(const ModInt &a) const {return val == a.val;}
inline constexpr bool operator!=(const ModInt &a) const {return val != a.val;}
inline constexpr auto& operator++(){*this += 1; return *this;}
inline constexpr auto& operator--(){*this -= 1; return *this;}
inline constexpr auto operator++(int){auto t = *this; *this += 1; return t;}
inline constexpr auto operator--(int){auto t = *this; *this -= 1; return t;}
inline constexpr static ModInt power(int64_t n, int64_t p){
if(p < 0) return power(n, -p).inv();
int64_t ret = 1, e = n % M;
for(; p; (e *= e) %= M, p >>= 1) if(p & 1) (ret *= e) %= M;
return ret;
}
inline constexpr static ModInt inv(int64_t a){
int64_t b = M, u = 1, v = 0;
while(b){
int64_t t = a / b;
a -= t * b; std::swap(a,b);
u -= t * v; std::swap(u,v);
}
u %= M;
if(u < 0) u += M;
return u;
}
inline constexpr static auto frac(int64_t a, int64_t b){return ModInt(a) / ModInt(b);}
inline constexpr auto power(int64_t p) const {return power(val, p);}
inline constexpr auto inv() const {return inv(val);}
friend inline constexpr auto operator-(const ModInt &a){return ModInt(-a.val);}
friend inline constexpr auto operator+(int64_t a, const ModInt &b){return ModInt(a) + b;}
friend inline constexpr auto operator-(int64_t a, const ModInt &b){return ModInt(a) - b;}
friend inline constexpr auto operator*(int64_t a, const ModInt &b){return ModInt(a) * b;}
friend inline constexpr auto operator/(int64_t a, const ModInt &b){return ModInt(a) / b;}
friend std::istream& operator>>(std::istream &s, ModInt<M> &a){s >> a.val; return s;}
friend std::ostream& operator<<(std::ostream &s, const ModInt<M> &a){s << a.val; return s;}
template <int N>
inline static auto div(){
static auto value = inv(N);
return value;
}
explicit operator int32_t() const noexcept {return val;}
explicit operator int64_t() const noexcept {return val;}
};
/**
* @title 1D Imos algorithm (Linear addition)
* @docs linear_imos_1d.md
*/
template <typename T> struct LinearImos1D{
std::vector<T> vec_a, vec_a_end, vec_b, vec;
int n;
LinearImos1D(int n): vec_a(n+1), vec_a_end(n+1), vec_b(n+1), vec(n+1), n(n){}
void add(int s, int t, const T &a, const T &b){ // x∈[s,t)ax+b
vec_a[s+1] += a;
vec_a[t] -= a;
vec_a_end[t] -= a * (t-s-1);
vec_b[s] += a * s + b;
vec_b[t] -= a * s + b;
}
void build(){
for(int i = 0; i < n; ++i) vec_a[i+1] += vec_a[i];
for(int i = 0; i <= n; ++i) vec_a[i] += vec_a_end[i];
for(int i = 0; i < n; ++i) vec_a[i+1] += vec_a[i];
for(int i = 0; i < n; ++i) vec_b[i+1] += vec_b[i];
for(int i = 0; i <= n; ++i) vec[i] = vec_a[i] + vec_b[i];
}
inline const T operator[](size_t i) const {return vec[i];}
};
using mint = ModInt<1000000007>;
const int MAX = 1000000000;
int main(){
int N;
while(std::cin >> N){
std::vector<int64_t> A(N);
for(int i = 0; i < N; ++i) std::cin >> A[i];
mint ans = 0;
if(std::count(A.begin(), A.end(), 0) == 0){
//std::vector<int64_t> p(N);
LinearImos1D<int64_t> p(N);
std::vector<int> next(N);
for(int i = N-1; i >= 0; --i){
if(A[i] == 1){
if(i == N-1) next[i] = N;
else{
if(A[i + 1] == 1){
next[i] = next[i + 1];
}else{
next[i] = i + 1;
}
}
}else{
next[i] = i + 1;
}
}
dump(next);
for(int l = 0; l < N; ++l){
int64_t prod = 1;
int r = l;
for(int i = 0; i < 100; ++i){
if(r == N or prod * A[r] >= MAX) break;
prod *= A[r];
r = next[r];
}
//for(int i = l; i < r; ++i){
// p[i] += r - i;
//}
p.add(l, r, -1, r);
}
p.build();
ans = 1;
for(int i = 0; i < N; ++i){
ans *= mint::power(A[i], p[i]);
}
}
std::cout << ans << "\n";
}
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0