結果
| 問題 |
No.3026 Range LCM (Online Version)
|
| コンテスト | |
| ユーザー |
shobonvip
|
| 提出日時 | 2025-02-14 23:13:49 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,712 bytes |
| コンパイル時間 | 3,382 ms |
| コンパイル使用メモリ | 239,372 KB |
| 実行使用メモリ | 201,084 KB |
| 最終ジャッジ日時 | 2025-02-14 23:20:00 |
| 合計ジャッジ時間 | 113,679 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge7 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| 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 = 4000;
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*=pg[largers[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*=pg[largers[j]];
}
}
}
rep(j,rt,r){
if (largers[j]>=0){
if (!nb[largers[j]]){
nb[largers[j]]=1;
ans*=pg[largers[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';
}
}
shobonvip