結果
問題 |
No.3026 Range LCM (Online Version)
|
ユーザー |
![]() |
提出日時 | 2025-02-14 23:16:58 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 3,682 bytes |
コンパイル時間 | 3,040 ms |
コンパイル使用メモリ | 239,892 KB |
実行使用メモリ | 205,584 KB |
最終ジャッジ日時 | 2025-02-14 23:24:52 |
合計ジャッジ時間 | 113,476 ms |
ジャッジサーバーID (参考情報) |
judge7 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 10 TLE * 26 |
ソースコード
/** author: shobonvip created: 2025.02.14 22:36:39 **/ #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> using namespace std; #include<atcoder/modint> #include<atcoder/segtree> using namespace atcoder; typedef modint998244353 mint; typedef long long ll; #define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++) #define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--) #define all(v) v.begin(), v.end() template <typename T> bool chmin(T &a, const T &b) { if (a <= b) return false; a = b; return true; } template <typename T> bool chmax(T &a, const T &b) { if (a >= b) return false; a = b; return true; } template <typename T> T max(vector<T> &a){ assert(!a.empty()); T ret = a[0]; for (int i=0; i<(int)a.size(); i++) chmax(ret, a[i]); return ret; } template <typename T> T min(vector<T> &a){ assert(!a.empty()); T ret = a[0]; for (int i=0; i<(int)a.size(); i++) chmin(ret, a[i]); return ret; } template <typename T> T sum(vector<T> &a){ T ret = 0; for (int i=0; i<(int)a.size(); i++) ret += a[i]; return ret; } int op(int a, int b) { return max(a, b); } int e() { return 0; } typedef bitset<18000> BTS; // importbisect template <typename T> int bisect_left(vector<T> &X, T v){ return lower_bound(X.begin(), X.end(), v) - X.begin(); } template <typename T> int bisect_right(vector<T> &X, T v){ return upper_bound(X.begin(), X.end(), v) - X.begin(); } // ----- mint plpow[100][30]; int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); const int mx = 200000; vector<int> pl; vector<int> pg; vector<bool> p(mx+1); rep(i,2,mx+1){ if(p[i])continue; if(i<=447) { pl.push_back(i); }else{ pg.push_back(i); } for(int j=i;j<=mx;j+=i){ p[j]=1; } } rep(i,0,(int)pl.size()){ plpow[i][0] = 1; rep(j,1,30){ plpow[i][j] = plpow[i][j-1] * pl[i]; } } int n; cin >> n; vector<int> a(n); vector<int> largers(n,-1); vector<segtree<int,op,e>> seg( (int)pl.size(), segtree<int,op,e>(n) ); rep(i,0,n) { cin >> a[i]; int tar = 0; for (int x: pl) { if (a[i] % x == 0) { int cnt = 0; while (a[i] % x == 0) { a[i] /= x; cnt++; } seg[tar].set(i, cnt); } tar++; } if (a[i] > 1) { largers[i] = bisect_left(pg,a[i]); } } const int B = 3000; int blocks = (n+B-1)/B; vector bg(blocks, vector<BTS>(blocks+1)); vector bans(blocks, vector<mint>(blocks+1,1)); rep(i,0,blocks) { int cnt=0; int v=0; BTS nb; mint nans=1; rep(j,i*B,n) { if (largers[j]>=0){ if (!nb[largers[j]]){ nb[largers[j]]=1; nans*=pg[largers[j]]; } } cnt++; if(cnt==B) { v++; bg[i][i+v]=nb; bans[i][i+v]=nans; cnt=0; } } } auto query = [&](int l, int r) -> mint { assert(0<=l&&r<=n); mint ans=1; rep(i,0,(int)pl.size()) { ans *= plpow[i][seg[i].prod(l,r)]; } if (l/B==r/B) { BTS nb; rep(j,l,r){ if (largers[j]>=0){ if (!nb[largers[j]]){ nb[largers[j]]=1; ans*=a[j]; } } } }else{ int lt = l+B-(l%B); int rt = r-(r%B); BTS nb = bg[lt/B][rt/B]; ans *= bans[lt/B][rt/B]; rep(j,l,lt){ if (largers[j]>=0){ if (!nb[largers[j]]){ nb[largers[j]]=1; ans*=a[j]; } } } rep(j,rt,r){ if (largers[j]>=0){ if (!nb[largers[j]]){ nb[largers[j]]=1; ans*=a[j]; } } } } return ans; }; int q; cin >> q; ll last_ans = 1; rep(i,0,q) { ll a, b; cin >> a >> b; int l = last_ans * a % 998244353 % n; int r = last_ans * b % 998244353 % n; if (l > r) swap(l, r); r++; last_ans = query(l,r).val(); cout << last_ans << '\n'; } }