如题,数组开大一点就 MLE,数组开小一点就 RE,有什么解决办法吗
//RE on test 30,空间已用 255MB
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9+7,maxn = 2e5+6,maxm = 1e6+5;
int n,l,r,q,a[maxn],f[maxn],g[maxm];
struct tree{int l,r,w;}t[maxn*105+100000];int tot,lst[maxm],pri[maxn],cnt,gg[maxn],rt[maxn];
bool vis[maxm];
void init(){
for(int i = 2;i < maxm-5;i ++){
if(!vis[i]) pri[++cnt] = i,g[i] = i;
for(int j = 1;j <= cnt && i * pri[j] < maxm-5;j ++){
vis[i * pri[j]] = 1,g[i * pri[j]] = pri[j];
if(i % pri[j] == 0) break;
}
}
}
int build(int l,int r){
int p = ++tot,mid = (l + r) / 2;t[p].w = 1;
if(l == r) return p;
t[p].l = build(l,mid),t[p].r = build(mid+1,r);
return p;
}
int update(int s,int l,int r,int x,int k){
int p = ++tot,mid = (l + r) / 2;t[p] = t[s],t[p].w = 1ll * t[p].w * k % mod;
if(l == r) return p;
if(x <= mid) t[p].l = update(t[p].l,l,mid,x,k);
else t[p].r = update(t[p].r,mid+1,r,x,k);
return p;
}
int query(int x,int s,int l,int r){
if(l == r) return t[s].w;
int mid = (l + r) / 2;
if(x <= mid) return 1ll * query(x,t[s].l,l,mid) * t[t[s].r].w % mod;
return query(x,t[s].r,mid+1,r);
}
int qp(int a,int b){
int ans = 1;
while(b) ans = (b & 1 ? 1ll * ans * a % mod : ans),a = 1ll * a * a % mod,b >>= 1;
return ans;
}
signed main(){ios::sync_with_stdio(false),cin.tie(0);
cin >> n,rt[0] = build(1,n),init(),f[0] = 1,gg[0] = 1;
for(int i = 1;i <= n;i ++) cin >> a[i],f[i] = 1ll * f[i-1] * a[i] % mod;
gg[n] = qp(f[n],mod-2);
for(int i = n;i >= 2;i --) gg[i-1] = 1ll * gg[i] * a[i] % mod;
for(int i = 1;i <= n;i ++){
int x = a[i];rt[i] = rt[i-1];
while(x > 1){
int y = g[x],tmp = 1ll * (y-1) * qp(y,mod-2) % mod;
while(x % y == 0) x /= y;
if(!lst[y]) rt[i] = update(rt[i],1,n,i,tmp);
else{int t = update(rt[i],1,n,lst[y],qp(tmp,mod-2)%mod);rt[i] = update(t,1,n,i,tmp);}
lst[y] = i;
}
}cin >> q;
while(q --){
cin >> l >> r;
cout << 1ll * gg[l-1] * f[r] % mod * query(l,rt[r],1,n) % mod << "\n";
}
return 0;
}