模意义下除法若结果仍为整数的话,可以记录模数的所有质因子,计算这些质因子的次幂数,剩余的exgcd解决。
$O(n\log n)$但有9的常数(1e9内的数最多有9个不同的质因子),T了。
1 #include<cstdio> 2 #include<algorithm> 3 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 4 using namespace std; 5 6 const int N=100010; 7 int T,n,mod,op,w,tot,res,x,d[N][11],p[11],s[11]; 8 9 void frac(int n){ 10 for (int i=2; i*i<=n; i++) if (n%i==0){ 11 p[++tot]=i; 12 while (n%i==0) n/=i; 13 } 14 if (n>1) p[++tot]=n; 15 } 16 17 void exgcd(int a,int b,int &x,int &y){ 18 if (!b) x=1,y=0; 19 else exgcd(b,a%b,y,x),y-=a/b*x; 20 } 21 22 int main(){ 23 freopen("bzoj5334.in","r",stdin); 24 freopen("bzoj5334.out","w",stdout); 25 for (scanf("%d",&T); T--; ){ 26 scanf("%d%d",&n,&mod); tot=0; res=1; frac(mod); 27 rep(i,1,10) s[i]=0; 28 rep(i,1,n){ 29 scanf("%d",&op); 30 if (op==1){ 31 scanf("%d",&w); 32 rep(j,0,tot) d[i][j]=0; 33 rep(j,1,tot) 34 while (w%p[j]==0) w/=p[j],d[i][j]++,s[j]++; 35 int x,y; res=1ll*res*w%mod; 36 exgcd(w,mod,x,y); d[i][0]=(x%mod+mod)%mod; 37 int ans=res; 38 rep(j,1,tot) rep(k,1,s[j]) ans=1ll*ans*p[j]%mod; 39 printf("%d\n",ans); 40 }else{ 41 scanf("%d",&x); res=1ll*res*d[x][0]%mod; 42 rep(j,1,tot) s[j]-=d[x][j]; 43 int ans=res; 44 rep(j,1,tot) rep(k,1,s[j]) ans=1ll*ans*p[j]%mod; 45 printf("%d\n",ans); 46 } 47 } 48 } 49 return 0; 50 }