POJ 2154 Color(polya定理+欧拉函数)

来源:互联网 发布:长兴人民法院淘宝拍卖 编辑:程序博客网 时间:2024/05/21 19:33
Color
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 10821 Accepted: 3499

Description

Beads of N colors are connected together into a circular necklace of N beads (N<=1000000000). Your job is to calculate how many different kinds of the necklace can be produced. You should know that the necklace might not use up all the N colors, and the repetitions that are produced by rotation around the center of the circular necklace are all neglected. 

You only need to output the answer module a given number P. 

Input

The first line of the input is an integer X (X <= 3500) representing the number of test cases. The following X lines each contains two numbers N and P (1 <= N <= 1000000000, 1 <= P <= 30000), representing a test case.

Output

For each test case, output one line containing the answer.

Sample Input

51 300002 300003 300004 300005 30000

Sample Output

131170629

Source

POJ Monthly,Lou Tiancheng

[Submit]   [Go Back]   [Status]   [Discuss]

Home Page   Go Back  To top


题意:给你n个珠子组成一个项链,让你用n种颜色给这n个珠子染色,

两个项链一样当前仅当旋转已经角度后能重合,问你组成项链的方案数。

题解:polya定理计数的模板题,然而这里n有10亿这么大,所以不能暴力找gcd(i,n)。
我们设l=n/gcd(n,i)为循环节的长度,则gcd(n,i)=n/l。
我们设cnt=gcd(n,i),表示循环节的个数。因为cnt一定是i的因数,故设i=cnt*x。
又因为n=cnt*l,故gcd(n,i)=gcd(cnt*l,cnt*x)=cnt,该等式成立当且仅当gcd(l,x)=1
此时问题转化为求gcd(l,x)=1,时x的个数,也就是求l的欧拉函数(不懂的自行百度欧拉函数)
总复杂度由O(nlog(n))变为O(sqrt(n)log(n))。。。。。
#include<set>      #include<map>         #include<stack>                #include<queue>                #include<vector>        #include<string>     #include<time.h>    #include<math.h>                #include<stdio.h>                #include<iostream>                #include<string.h>                #include<stdlib.h>        #include<algorithm>       #include<functional>        using namespace std;                #define ll long long          #define inf 1000000000         #define mod 1000000007                 #define maxn  50005    #define lowbit(x) (x&-x)                #define eps 1e-9    int a[maxn]={1,1},b[maxn],cnt;void init(){ll i,j;for(i=2;i<maxn;i++){if(a[i])continue;b[++cnt]=i;for(j=i*i;j>0 && j<maxn;j+=i)a[j]=1;}}ll ol(ll x)  {      ll i,res=x;      for(i=1;i<=cnt && b[i]*b[i]<=x;i++)      {          if(x%b[i]==0)          {              res=res-res/b[i];              while(x%b[i]==0)                  x/=b[i];          }      }      if(x>1)          res=res-res/x;      return res;  } int q(int x,int y,int p)    {        int res=1; x=x%p;    while(y)        {            if(y%2)                res=res*x%p;            x=x*x%p;            y/=2;        }        return res;    }    int main(void)    {    init();    int n,i,j,p,t;scanf("%d",&t);    while(t--)        {    int ans=0;scanf("%d%d",&n,&p);for(i=1;i*i<=n;i++){if(n%i==0){ans=(ans+ol(i)%p*q(n,n/i-1,p))%p;if(i*i==n)break;ans=(ans+ol(n/i)%p*q(n,i-1,p))%p;}}        printf("%d\n",ans);        }        return 0;    }  


原创粉丝点击