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
原创粉丝点击