This "Violence segment tree" can think about is not what special properties.
This question is for what to know:
Here may be written more clearly ( Excerpt )
Feeling process is an iterative process.
And a number of times after the operation k can no longer operate.
Euler's theorem then use the time to look at special sentence:
x> time = phi, and finally to add a phi
Not less than plus.
All of the pre-phi, phi remember the last one.
#include<bits/stdc++.h> #define LL long long #define N 50003 using namespace std; int read() { int x=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x*f; } LL n,m,p,c; LL num=0; LL a[N],P[N]; int ok=0; LL quick(LL a,LL x,LL mod) { LL ans=1; while(x) { if(x&1)ans=ans*a; a=a*a;x>>=1; if(ans>=mod)ok=1,ans%=mod; if(a>=mod)ok=1,a%=mod; } return ans; } int phi(int x) { int ans=x; for(int i=2;i*i<=x;++i) { if(x%i==0) { ans=ans/i*(i-1); while(x%i==0)x/=i; } } if(x!=1)ans=ans/x*(x-1); return ans; } LL sum[N<<2],ge[N<<2]; void pushup(int k) { sum[k]=(sum[k<<1]+sum[k<<1|1])%p; ge[k]=min(ge[k<<1],ge[k<<1|1]); } void build(int k,int l,int r) { if(l==r){sum[k]=a[l]%p;return;} int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); pushup(k); } LL query(int k,int L,int R,int l,int r) { LL ans=0; if(L>=l&&R<=r)return sum[k]; int mid=(L+R)>>1; if(l<=mid) { ans+=query(k<<1,L,mid,l,r); if(ans>=p)ans%=p; } if(r>mid) { ans+=query(k<<1|1,mid+1,R,l,r); if(ans>=p)ans%=p; } return ans%p; } LL cal(LL x,LL times) { if(x>P[times]) x=x%P[times]+P[times]; for(int i=times;i>=1;--i)//类似迭代求解 { ok=0;//特判一下 x=quick(c,x,P[i-1]); if(ok) x+=P[i-1]; } Return X; } void Modify ( int K, int L, int R & lt, int L, int R & lt) { if (GE [K]> = NUM) return ; // exceeded the maximum number will not changed if (L == R & lt) { SUM [K] = CAL (A [L], GE ++ [K])% P; return ; } int MID = (L + R & lt) >> . 1 ; IF (L <= MID ) Modify (K << . 1 , L, MID, L, R & lt); IF (R & lt> MID) Modify (K << . 1 | . 1,mid+1,R,l,r); pushup(k); } int main() { // freopen("verbinden.in","r",stdin); // freopen("verbinden.out","w",stdout); n=read(),m=read(),p=read(),c=read(); int q=p; num=0; P[0]=q; while(q!=1)//预处理出phi { q=P[++num]=phi(q); } P[++num]=1; int flagg=0; for(int i=1;i<=n;++i)a[i]=read(); build(1,1,n); for(int i=1;i<=m;++i) { int op=read(),l=read(),r=read(); if(op==0) { modify(1,1,n,l,r);//a[i]=quick(c,a[i]); } else if(op==1) { LL ans=0; printf("%lld\n",query(1,1,n,l,r)%p); } } }