poj2154 polya theory

来源:互联网 发布:js设置页面刷新 编辑:程序博客网 时间:2024/06/08 13:20

解法与ploya入门题一样,但要用 euler 函数优化

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<bitset>using namespace std;typedef long long ll;template<typename T>T operator % (T a,T b){return a>=b?a%b:a;}const int maxn = 111111;bitset<maxn>a;int p[maxn],size=0;int f[1111],c[1111],cnt;int divisor[1111],tsize;int m;void init(){    int i,j;    a[0]=a[1]=1;    for(i=2; i*i<=33000; ++i)        if(!a[i])            for(j=i*i; j<=33000; a[j]=1,j+=i);                               for(i=2; i<=33000; ++i)        if(!a[i])            p[size++]=i;       }void split(int n)// 分解质因数 {    int t=n,i,j;    cnt=0;    memset(c,0,sizeof(c));    for(i=0; 1ll*p[i]*p[i]<=t&&i<size; ++i)    {        if(t%p[i]==0)        {            f[cnt]=p[i];            while(t%p[i]==0)            {                c[cnt]++;                t/=p[i];            }            cnt++;        }    }    if(t>1)    {        c[cnt]++;        f[cnt]=t;        ++cnt;    }}void dfs(int s,int k){    if(k==cnt)    {        divisor[tsize++]=s;        return ;    }    for(int i=0; i<=c[k]; s*=f[k],++i)    {        dfs(s,k+1);    }}int euler(int n){    int i,res=n,t=n;    for(i=0; 1ll*f[i]*f[i]<=t&&i<cnt; ++i)    {        if(t%f[i]==0)        {            res=res-res/f[i];            while(t%f[i]==0)            {                t/=f[i];            }        }    }    if(t>1) res=res-res/t;    return res;}ll cal(int a,int b){    ll res=1,t=a;    while(b)    {        if(b&1) res=res*t%m;        t=t*t%m;        b>>=1;    }    return res;}int main(){    init();    ios::sync_with_stdio(false);    int t,d,n,T,i;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        split(n);        tsize=0;        dfs(1,0);        ll ans=0;        for(i=0; i<tsize; ++i)        {            d=divisor[i];            t=euler(n/d);            ans+=t*cal(n,d-1);//burnside leme 注意到要除以n 故此计算一次置换时每个等价类的染色数目相当于 n-1             ans%=m;        }        printf("%lld\n",ans);    }    return 0;}


原创粉丝点击