奇数国[清华集训2014 Day1]
SOL
奇奇怪怪的题目,我们发现我们的值对答案的贡献,发现其的大于281的质因数对答案无贡献,那么我们可以用一个60大小的数组来表示一个数。一个区间的答案就是其积的欧拉函数值,那么我们用树状数组维护。(常数有点大)
#pragma optimize("-O2") #include<bits/stdc++.h> #define LL long long #define mo 19961993 #define getchar nc #define N 100007 #define L(x) (x&-x) #define sight(c) ('0'<=c&&c<='9') #define bug 1000007 using namespace std; int pim[60]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53, 59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131, 137,139,149,151,157,163,167,173,179,181,191,193,197,199, 211,223,227,229,233,239,241,251,257,263,269,271,277,281}; inline char nc() { static char buf[bug],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,bug,stdin),p1==p2)?EOF:*p1++; } inline void read(int &x){ static char c;static int b; for (b=1,c=getchar();!sight(c);c=getchar())if (c=='-')b=-1; for (x=0;sight(c);c=getchar()) x=x*10+c-48; x*=b; } inline void read(LL &x){ static char c;static int b; for (b=1,c=getchar();!sight(c);c=getchar())if (c=='-')b=-1; for (x=0;sight(c);c=getchar()) x=x*10+c-48; x*=b; } void write(LL x) { if (x<10) { putchar('0'+x); return;} write(x/10); putchar('0'+x%10);} inline void writeln(LL x) {if (x<0) putchar('-'),x*=-1; write(x); putchar('\n');} inline LL qsm(LL x,LL y){ LL anw=1; for(;y;y>>=1,(x*=x)%=mo) if (y&1) (anw*=x)%=mo; return anw; } struct Seg{ int t[60]; inline LL ola(){ LL an=1; for (int i=59;~i;i--) if (t[i]) (an*=(pim[i]-1)*qsm(pim[i],t[i]-1))%=mo; return an; } inline void rub(int x){ memset(t,0,sizeof t); for (int i=59;~i;i--) while (!(x%pim[i])) t[i]++,x/=pim[i]; } inline void operator += (const Seg& A){ for (int i=59;~i;i--) t[i]+=A.t[i]; } inline void operator -= (const Seg& A){ for (int i=59;~i;i--) t[i]-=A.t[i]; } }S[N]; Seg opt,T,TT; inline Seg operator +(const Seg &X,const Seg &Y){ for (int i=59;~i;i--) T.t[i]=Y.t[i]+X.t[i]; return T; } inline Seg operator -(const Seg &X,const Seg &Y){ for (int i=59;~i;i--) T.t[i]=X.t[i]-Y.t[i]; return T; } int tot,t[N]; Seg L; void pre(){ L.t[1]=1; for (int i=1;i<N;i++) t[i]=3,S[i].t[1]=L(i); } int m,op,b,c; Seg T1,T2; int main () { pre(); read(m); while (m--) { read(op); switch (op) { case 0: read(b);read(c); memset(opt.t,0,sizeof opt.t); for (int x=c;x;x-=L(x)) opt+=S[x]; for (int x=b-1;x;x-=L(x)) opt-=S[x]; writeln(opt.ola()); break; case 1: read(b); read(c); T1.rub(c); T2.rub(t[b]); L=T1-T2; for (int x=b;x<N;x+=L(x)) S[x]+=L; t[b]=c; break; } } return 0; }