POJ 2154

这题的时间卡的。。。。

必须用欧拉来优化,而且要加素数表。最重要是,因为最后结果要/n,而数据很大,所以,必须在之前就先/n了,否则会爆数据。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#define LL __int64
using namespace std;

int fact[1000],fp;
bool isprime[35000];
int prime[35000],np;

void getprime(){
	np=0;
	memset(isprime,true,sizeof(isprime));
	for(int i=2;i<35000;i++){
		if(isprime[i]){
			prime[np++]=i;
			for(int j=i*i;j<35000;j+=i)
			isprime[j]=false;
		}
	}
}

int Power(int a,int b,int m){
	int ans=1;
	a=a%m;
	while(b){
		if(b&1) ans=(ans*a)%m;
		a=(a*a)%m;
		b=b>>1;
	}
	return ans;
}

int Euler(int s){
	int res=s;
	for(int i=0;i<np&&prime[i]*prime[i]<=s;i++){
		if(s%prime[i]==0){
			res=res-res/prime[i];
			while(s%prime[i]==0)
			s=s/prime[i];
		}
	}
	if(s>1)
	res=res-res/s;
	return res;
}

void Burnside(int n,int p){
	fp=0;
	for(int i=1;i*i<=n;i++){
		if(n%i==0){
			fact[fp++]=i;
			if(n/i!=i)
			fact[fp++]=n/i;
		}
	}
	int ans=0;
	for(int i=0;i<fp;i++){
		ans=(ans+Power(n,fact[i]-1,p)*((Euler(n/fact[i]))%p))%p;  //此处是fact[i]-1表明 除以n,这是因为为了MOD P
	}
	ans%=p;
	printf("%d\n",ans);
}

int main(){
	getprime();
	int T,n,p;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&p);
		Burnside(n,p);
	}
	return 0;
}

  

时间: 2024-11-06 07:43:06

POJ 2154的相关文章

[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 ——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) #de

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 【POLYA】【欧拉】

前记: TM终于决定以后干啥了.这几天睡的有点多.困饿交加之间喝了好多水.可能是灌脑了. 切记两件事: 1.安心当单身狗 2.顺心码代码 题意: 给你N种颜色的珠子,串一串长度问N的项链,要求旋转之后重合的算是同一种项链.问一共有多少中可能.结果模p. 1 <= N <= 1000000000, 1 <= P <= 30000 思路: 首先是我们的POLYA定理,给定的公式是这样的sigma(N^gcd(N,i))/N   i从0到N-1. 然后是优化的问题.因为如果我们枚举i累加

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 *