只有迴圈同構。n很大,必須用歐拉函數來最佳化一下計算。計算較大數的歐拉函數可以直接枚舉質因子來算,應該遠小於 n√ \sqrt n。
為什麼大家都跑的那麼快呀orz,是蒟蒻姿勢不對麼
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;#define inf 0x3f3f3f3f#define ll long long#define N 100010inline char gc(){ static char buf[1<<16],*S,*T; if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;} return *S++;}inline int read(){ int x=0,f=1;char ch=gc(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc(); return x*f;}int tst,mod,n,prime[N],phi[N],tot=0;bool notprime[N];inline void init(){ notprime[1]=1;phi[1]=1; for(int i=2;i<=100000;++i){ if(!notprime[i]) prime[++tot]=i,phi[i]=i-1; for(int j=1;prime[j]*i<=100000;++j){ notprime[prime[j]*i]=1; if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;} phi[i*prime[j]]=phi[i]*phi[prime[j]]; } }}inline int ksm(int x,int k){ x%=mod;int res=1;for(;k;k>>=1,x=x*x%mod) if(k&1) res=res*x%mod;return res;}inline int ph(int x){ if(x<=100000) return phi[x]%mod; int res=x,xx=x; for(int j=1;prime[j]*prime[j]<=x&&xx!=1;++j){ if(xx%prime[j]==0) res-=res/prime[j]; while(xx%prime[j]==0) xx/=prime[j]; }if(xx!=1) res-=res/xx;return res%mod;}int main(){// freopen("a.in","r",stdin); tst=read();init(); while(tst--){ n=read();mod=read();int ans=0;int x=1; for(;x*x<n;++x) if(n%x==0) ans+=ksm(n,x-1)*ph(n/x)+ksm(n,n/x-1)*ph(x),ans%=mod; if(x*x==n) ans+=ksm(n,x-1)*ph(x);ans%=mod; printf("%d\n",ans); }return 0;}