(并不能)发现29393不是质数,而是等于7*13*17*19
于是可以用四个线段树分别维护模意义下,对x进行一个区间的操作后的值
最后再把这四个的答案用crt拼起来
也可以不crt,而是预处理0~29392的每个情况
为了降低复杂度,预处理模7/13/17/19的幂
注意询问时,要把询问对7/13/17/19先取模
复杂度$O((7+13+17+19)nlogn)$
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define pa pair<int,int> 5 #define CLR(a,x) memset(a,x,sizeof(a)) 6 using namespace std; 7 const int maxn=5e4+10; 8 9 inline int rd(){ 10 int x=0;char c=getchar();int neg=1; 11 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 12 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 13 return x*neg; 14 } 15 16 struct Node{ 17 int op,v; 18 }; 19 20 int Pow[20][20][20],ans[10][15][20][20]; 21 22 inline void init_pow(int x){ 23 for(int i=0;i<x;i++){ 24 Pow[x][i][0]=1; 25 for(int j=1;j<x-1;j++) Pow[x][i][j]=Pow[x][i][j-1]*i%x; 26 } 27 } 28 29 inline int fpow(int x,int y,int mod){ 30 return Pow[mod][x%mod][y%(mod-1)]; 31 } 32 33 inline int cal(int x,Node y,int mod){ 34 if(y.op==1) return (x+y.v)%mod; 35 else if(y.op==2) return x*y.v%mod; 36 else return fpow(x,y.v,mod); 37 } 38 39 struct SegT{ 40 int trans[maxn<<2][20],mod; 41 42 inline void update(int p){ 43 int a=p<<1,b=p<<1|1; 44 for(int i=0;i<mod;i++){ 45 trans[p][i]=trans[b][trans[a][i]]; 46 } 47 } 48 inline void change(int p,int l,int r,int x,Node y){ 49 if(l==r){ 50 for(int i=0;i<mod;i++) trans[p][i]=cal(i,y,mod); 51 }else{ 52 int m=(l+r)>>1; 53 if(x<=m) change(p<<1,l,m,x,y); 54 else change(p<<1|1,m+1,r,x,y); 55 update(p); 56 } 57 } 58 }tr[4]; 59 60 int N,M; 61 62 inline Node getnode(){ 63 char s[10];Node x; 64 scanf("%s",s); 65 if(s[0]=='+') x.op=1; 66 else if(s[0]=='*') x.op=2; 67 else x.op=3; 68 x.v=0; 69 for(int k=1,j=strlen(s);k<j;k++) x.v=x.v*10+s[k]-'0'; 70 return x; 71 } 72 73 inline int solve(int x){ 74 int a[5]; 75 for(int i=0;i<4;i++) a[i]=tr[i].trans[1][x%tr[i].mod]; 76 return ans[a[0]][a[1]][a[2]][a[3]]; 77 } 78 79 int main(){ 80 int i,j,k; 81 tr[0].mod=7,tr[1].mod=13,tr[2].mod=17,tr[3].mod=19; 82 init_pow(7),init_pow(13),init_pow(17),init_pow(19); 83 for(i=0;i<29393;i++){ 84 ans[i%7][i%13][i%17][i%19]=i; 85 } 86 for(int T=rd(),t=1;t<=T;t++){ 87 for(i=0;i<4;i++){ 88 for(j=1;j<=4*N;j++){ 89 for(k=0;k<tr[i].mod;k++) 90 tr[i].trans[j][k]=k; 91 } 92 } 93 printf("Case #%d:\n",t); 94 N=rd(),M=rd(); 95 for(i=1;i<=N;i++){ 96 Node x=getnode(); 97 for(j=0;j<4;j++) tr[j].change(1,1,N,i,x); 98 } 99 for(i=1;i<=M;i++){ 100 int a=rd(); 101 if(a==1){ 102 printf("%d\n",solve(rd())); 103 }else{ 104 int x=rd();Node y=getnode(); 105 for(j=0;j<4;j++) tr[j].change(1,1,N,x,y); 106 } 107 } 108 } 109 return 0; 110 }