您的位置:首页 > 其它

poj_2154

2015-08-26 14:32 295 查看
polya+euler+素数优化=1200ms+

[code]/*
ID: CaoLei
PROG: poj_2154.cpp
LANG: 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 100000000
typedef 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: