操作过程中标记传递 询问的时候再计算
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define pb push_back #define CLR(A,v) memset(A,v,sizeof A) // #define inf 0x3f3f3f3f #define lson l,m,pos<<1 #define rson m+1,r,pos<<1|1 const int N=100000+5; const int mod=1e9+7; int f[N*10],prime[N*10],pre[N*10],cnt;void init() {f[1]=1;prime[0]=prime[1]=1;rep(i,2,1e6){if(prime[i]==0){pre[++cnt]=i;f[i]=i;}for(int j=1;j<=cnt&&pre[j]*i<=1e6;j++){prime[i*pre[j]]=1;f[i*pre[j]]=pre[j];if(i%pre[j]==0)break;}} }ll fast(ll x,ll n) {ll ans=1;while(n){if(n&1)ans=(ans*x)%mod;x*=x;x%=mod;n>>=1;}return ans%mod; }ll sum[N<<2],col[N<<2];void up(int pos) {sum[pos]=sum[pos<<1]+sum[pos<<1|1]; }void down(int pos) {col[pos<<1]+=col[pos];col[pos<<1|1]+=col[pos];col[pos]=0; }void build(int l,int r,int pos) {if(l==r){scanf("%lld",&sum[pos]);col[pos]=0;return ;}int m=(l+r)>>1;build(lson);build(rson);up(pos); }void update1(int L,int R,int l,int r,int pos) {if(sum[pos]==r-l+1)return ;if(L<=l&&r<=R){col[pos]++;return ;}down(pos);int m=(l+r)>>1;if(L<=m)update1(L,R,lson);if(R>m)update1(L,R,rson);up(pos); }void update2(int L,int R,int l,int r,int pos) {if(sum[pos]==r-l+1)return ;if(L<=l&&r<=R&&col[pos]){col[pos]--;return ;}if(l==r){sum[pos]=sum[pos]/f[sum[pos]]%mod;return ;}down(pos);int m=(l+r)>>1;if(L<=m)update2(L,R,lson);if(R>m)update2(L,R,rson);up(pos); }ll query(int x,int l,int r,int pos) {if(sum[pos]==r-l+1)return 1;if(l==r){return sum[pos]*fast(f[sum[pos]],col[pos])%mod;}down(pos);int m=(l+r)>>1;if(x<=m)return query(x,lson);else return query(x,rson); }int main() {init();int n,m;RII(n,m);build(1,n,1);int q,a,b;while(m--){RI(q);if(q==1){RII(a,b);update1(a,b,1,n,1);}else if(q==2){RII(a,b);update2(a,b,1,n,1);}else if(q==3){RI(a);cout<<query(a,1,n,1)<<endl;}}return 0; }