4869: [Shoi2017]相逢是問候
先說點正經的……
顯然做了有限次(我只知道是有限次,而且不會大,別人說是log次?)修改以后會達到不動點,即以后怎么修改都不變了。
然后就隨便做了。(3個log不知道是不是暴力啊)
但是需要拓展歐拉定理:
p與a不互質時,設c=b mod φ(p)(專門設出來是因為公式不能正常顯示),如果b>=φ(p):$a^b ≡ a^{c+φ(p)}$(注意b<φ(p)的時候不能用)
要證明的話可以用數學歸納法證。
可是題目翻車了……
大家都質疑題目數據有問題
得知這一點,窩的瓜心是崩潰的。
這可是省選題,關系到六個省的oier的命運。
我認識的幾位dalao就參加了這場省選,有的進隊,有的從此AFO。
過幾天我也要省選了,要是出了類似的差錯被卡退役,西瓜可是不會同意的。
為退役的選手們惋惜,也只能祝他們高考加油了。
(也許過幾天就輪到我了呢?
瓜之將死,其言也善
upd:后來bzoj上數據更正了呢

#include<cstdio> #include<algorithm> #define MN 100001 #define lp p<<1 #define rp (p<<1)|1 using namespace std; int read_p,read_ca; inline int read(){ read_p=0;read_ca=getchar(); while(read_ca<'0'||read_ca>'9') read_ca=getchar(); while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar(); return read_p; } int n,m,MOD,c,w=0,S[MN],W[MN],a[MN],P[MN],num=0,t,l,r,sum[MN<<2]; bool bo[MN<<2],bi[MN]; inline void M(int &x){while(x>=MOD)x-=MOD;} inline int mi(int x,int y,int MOD,bool &bi){ int mmh=1; bool fx=0; while (y){ if (y&1) bi|=fx|(1LL*x*mmh>=MOD),mmh=1LL*mmh*x%MOD; fx|=1LL*x*x>=MOD;x=1LL*x*x%MOD;y>>=1; } return mmh; } inline int phi(int p){ int o=1; for (int i=1;P[i]*P[i]<=p&&i<=num;i++) if (p%P[i]==0){ p/=P[i];o*=P[i]-1; while (p%P[i]==0) p/=P[i],o*=P[i]; } if (p-1) o*=p-1; return o; } void work(int p){ S[w++]=p; if (p==1) return; work(phi(p)); } int Mavis(int a,int L){ int mmh=a%S[L]; bool bi=a>=S[L]; for (int k=L;k;k--) mmh=mi(c,mmh+(bi?S[k]:0),S[k-1],bi); return mmh; } void cg(int p,int l,int r,int L,int R){ if (bo[p]) return; if (l==r) {W[l]++;bo[p]=(W[l]==w-1);sum[p]=Mavis(a[l],W[l]);return;} int mid=l+r>>1; if (R<=mid) cg(lp,l,mid,L,R);else if (L>mid) cg(rp,mid+1,r,L,R);else cg(lp,l,mid,L,mid),cg(rp,mid+1,r,mid+1,R); bo[p]=bo[lp]&bo[rp]; M(sum[p]=sum[lp]+sum[rp]); } void build(int p,int l,int r){ bo[p]=0; if (l==r) sum[p]=a[l];else{ int mid=l+r>>1; build(lp,l,mid);build(rp,mid+1,r); M(sum[p]=sum[lp]+sum[rp]); } } int ask(int p,int l,int r,int L,int R){ if (l>=L&&r<=R) return sum[p]; if (l>R||r<L) return 0; int mid=l+r>>1; return (ask(lp,l,mid,L,R)+ask(rp,mid+1,r,L,R))%MOD; } int main(){ register int i,j,k; n=read();m=read();MOD=read();c=read(); for (i=2;i*i<=MOD;i++){ if (!bo[i]) P[++num]=i; for (j=1;j<=num&&i*P[j]*i*P[j]<=MOD;j++) if (bo[i*P[j]]=1,i%P[j]==0) break; } work(MOD);S[w++]=1; for (i=1;i<=n;i++) a[i]=read(),W[i]=0; build(1,1,n); while (m--) if (t=read(),l=read(),r=read(),t==0) cg(1,1,n,l,r);else printf("%d\n",ask(1,1,n,l,r)); }
upd:后來我退役了呢