poj2154Color

来源:互联网 发布:js iframe 子页面跳转 编辑:程序博客网 时间:2024/06/06 12:56

polyd计数问题,题意是给你n个珠子n种染料,可以旋转,可以有多少种不等价的染色方案。ps:一定要慎重处理取余的运算,不是素数的mod,个人拙见,如不对请指正。

#include<cstdio>#include<map>#include<vector>#include<algorithm>#include<iostream>using namespace std;typedef long long ll;ll n;int mod;int T;ll mod_pow(ll x,ll n,int MOD){    ll res=1;    while(n>0)    {        if(n&1)res=res*x%MOD;        x=x*x%MOD;        n>>=1;    }    return res;}map<int ,int> prime_factor(int n){    map<int , int>res;    for(int i=2; i*i<=n; i++)    {        while(n%i==0)        {            ++res[i];            n/=i;        }    }    if(n!=1)        res[n]=1;    return res;}vector<int> divisor(int n){    vector<int> res;    for(int i=1; i*i<=n; i++)    {        if(n%i==0)        {            res.push_back(i);            if(i!=n/i)res.push_back(n/i);        }    }    return res;}void solve(){    map<int ,int>primes = prime_factor(n);    vector<int>divs=divisor(n);    ll res=0;    for(int i=0; i<divs.size(); i++)    {        ll euler = divs[i];        for(map<int ,int>::iterator it = primes.begin(); it!=primes.end(); ++it)        {            int p = it->first;            if(divs[i]%p == 0)euler = euler / p * (p - 1);        }        res+=euler*mod_pow(n,n/divs[i]-1,mod)%mod;        res%=mod;    }    printf("%lld\n",res);}int main(){    scanf("%d",&T);    while(T--)    {        scanf("%lld %d",&n,&mod);        solve();    }    return 0;}


0 0
原创粉丝点击