poj_2154
来源:互联网 发布:java 构造器 构造方法 编辑:程序博客网 时间:2024/05/21 11:35
polya+euler+素数优化=1200ms+
/*ID: CaoLeiPROG: poj_2154.cppLANG: C++*/#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#include <set>#include <queue>#include <map>#include <cmath>#include <vector>using namespace std;#define N 1000010#define pi acos(-1.0)#define inf 100000000typedef int ll;typedef unsigned long long ull;int prime[35001];bool is[35001];void p_table(){ int p=0; for(int i=2;i<=35000;i++){ if(!is[i]){ prime[++p]=i; for(int j=2*i;j<=35000;j+=i){ is[j]=true; } } }}int euler_phi(int n){ int m=(int)sqrt(n+0.5); int ans=n; for(int i=1;prime[i]<=m;i++){ if(n%prime[i]==0){ ans=ans/prime[i]*(prime[i]-1); while(n%prime[i]==0) n/=prime[i]; } } if(n>1) ans=ans/n*(n-1); return ans;}ll pow(ll a,ll m,ll p){ ll ans=1,tmp=a; while(m){ if(m&1){ ans*=tmp; ans%=p; } tmp*=tmp; tmp%=p; m>>=1; } return ans;}ll n,p;ll polya(){ ll ans=0,c=n; for(int i=1;i*i<=n;i++){ if(n%i==0){ ans=(ans+euler_phi(n/i)%p*pow(n%p,i-1,p)%p)%p; if(i != n/i) //枚举另一边 ans = (ans + euler_phi(i)%p * pow(n%p, n/i-1, p)) % p; } } return ans;}int main(){ freopen("in.txt","r",stdin); p_table(); int t; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&p); printf("%d\n",polya()); } return 0;}
0 0