POJ 2154 Color ——Burnside引理

【题目分析】

数据范围有些大。

然后遍求欧拉函数,遍求和就好了,注意取模。

【代码】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define maxn 100005
#define inf 0x3f3f3f3f

int n,p,x,sum;
int ispr[maxn],pr[maxn],top=0;

void init()
{
	F(i,2,maxn-1)
		if (!ispr[i])
		{
			pr[++top]=i;
			F(j,2,inf)
			{
				if (j*i>=maxn) break;
				ispr[j*i]=1;
			}
		}
}

int qpow(int a,int b)
{
	a%=p;
	int ret=1;
	while (b)
	{
		if (b&1) (ret*=a)%=p;
		(a*=a)%=p;
		b>>=1;
	}
	return ret;
}

int phi(int n)
{
	int ret=n;
	for (int i=1;pr[i]*pr[i]<=n&&i<=top;++i)
		if (n%pr[i]==0)
		{
			ret=ret-ret/pr[i];
			while (n%pr[i]==0) n/=pr[i];
		}
	if (n>1) ret=ret-ret/n;
	return ret%p;
}

int main()
{
	init();
//	F(i,1,top) printf("%d ",pr[i]); printf("\n");
	scanf("%d",&x);
	while (x--)
	{
		sum=0;
		scanf("%d%d",&n,&p);
		for (int i=1;i*i<=n;++i)
		{
			if (n%i==0)
			{
				sum=(sum+(qpow(n,i-1)*phi(n/i))%p)%p;
				if (i*i!=n) sum=(sum+(qpow(n,n/i-1)*phi(i))%p)%p;
			}
		}
		printf("%d\n",sum);
	}
}

  

时间: 2024-08-05 19:43:15

POJ 2154 Color ——Burnside引理的相关文章

[ACM] POJ 2154 Color (Polya计数优化,欧拉函数)

Color Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7630   Accepted: 2507 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 th

poj 2154 Color(polya计数 + 欧拉函数优化)

http://poj.org/problem?id=2154 大致题意:由n个珠子,n种颜色,组成一个项链.要求不同的项链数目,旋转后一样的属于同一种,结果模p. n个珠子应该有n种旋转置换,每种置换的循环个数为gcd(i,n).如果直接枚举i,显然不行.但是我们可以缩小枚举的数目.改为枚举每个循环节的长度L,那么相应的循环节数是n/L.所以我们只需求出每个L有多少个i满足gcd(i,n)= n/L,就得到了循环节数为n/L的个数.重点就是求出这样的i的个数. 令cnt = gcd(i,n) =

POJ 2154 Color(组合数学-波利亚计数,数论-欧拉函数,数论-整数快速幂)

Color Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7693   Accepted: 2522 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 th

poj 2154 Color 欧拉函数优化的ploya计数

枚举位移肯定超时,对于一个位移i,我们需要的是它的循环个数,也就是gcd(i,n),gcd(i,n)个数肯定不会很多,因为等价于n的约数的个数. 所以我们枚举n的约数,对于一个约数k,也就是循环个数为n/k这样的个数有phi[k]种,证明网上有很多.所以答案就是 phi[k]*(pow(n,n/k)) (k是n的所有约数) 由于约数会很大所以不能打表,只能单个算. 再由于最后要除以n,如果做除法就不能直接取模,所以我们在算每一次pow(n,n/k)的时候,都少乘一个n,这样就相当于除法了. #i

组合数学 - 波利亚定理 --- poj : 2154 Color

Color Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7873   Accepted: 2565 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 th

poj 2154 Color

这是道标准的数论优化的polya题.卡时卡的很紧,需要用int才能过.程序中一定要注意控制不爆int!!!我因为爆intWA了好久=_=…… 题目简洁明了,就是求 sigma n^gcd(i,n):但是由于n很大,所以直接暴力枚举必然会T.于是我们按照这种题的通常思路按gcd的值分类. gcd(i, n) = 1 的个数很明显为 phi(n); gcd(i, n) = 2 -> gcd(i/2, n/2) = 2 所以个数为 phi(n/2); 这样就ok了, 我们就是要求 sigma phi(

POJ 2154 Color (ploya欧拉函数)

ploya定理,然后公式利用欧拉函数优化,gcd必然是因子,这样只要枚举因子,每个因子利用欧拉函数计算出现次数 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int t, n, p; int pow_mod(int x, int k) { x %= p; int ans = 1; while (k) { if (k&1) ans = ans *

POJ 2154 color (菜啊)

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

Polya定理,Burnside引理(转)

设G是一个集合,*是G上的二元运算,如果(G,*)满足下面的条件: 封闭性:对于任何a,b∈G,有a*b∈G; 结合律:对任何a,b,c∈G有(a*b)*c=a*(b*c); 单位元:存在e∈G,使得对所有的a∈G,都有a*e=e*a=a; 逆元:对于每个元素a∈G,存在x∈G,使得a*x=x*a=e,这个时候记x为a-1,称为a的逆元,那么则称(G,*)为一个群. 例:G={0,1,2,3,4....n-1}那么它在mod n加法下是一个群. 群元素的个数有限,称为有限群,且其中元素的个数称为