poj 2154 Color(polya计数 + 欧拉函数优化)
来源:互联网 发布:java 社招 经验 编辑:程序博客网 时间:2024/05/30 23:43
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) = n/L;
那么cnt | i,令i = cnt*t(0 <= t <= L);
又 n = cnt * L ;
所以gcd(i,n) = gcd( cnt*t, cnt*L) = cnt,
满足上式的条件是 gcd(t,L) = 1。
而这样的t 有Eular(L)个。
因此循环节个数是n/L的置换个数有Eular(L)个。
参考博客:http://blog.csdn.net/tsaid/article/details/7366708
代码中求欧拉函数是基于素数筛的,素数只需筛到sqrt(1e9)即可。我在筛素数的同时递推的记录了sqrt(1e9)以内的Eular(n),用phi[]表示。这样会快那么一点点。
#include <stdio.h>#include <iostream>#include <algorithm>#include <set>#include <map>#include <vector>#include <math.h>#include <string.h>#include <queue>#include <string>#include <stdlib.h>#define LL long long#define _LL __int64#define eps 1e-8#define PI acos(-1.0)using namespace std;const int maxn = 35000;const int INF = 0x3f3f3f3f;int n,p;int ans;int prime[maxn];int flag[maxn];int prime_num;int phi[maxn];int mod_exp(int a, int b, int c){int res = 1;a = a%c;while(b){if(b&1)res = (res*a)%c;a = (a*a)%c;b >>= 1;}return res;}//素数筛并记录maxn以内的Eular(n),用phi[]表示void get_prime(){memset(flag,0,sizeof(flag));prime_num = 0;phi[1] = 1;for(int i = 2; i <= maxn; i++){if(!flag[i]){prime[++prime_num] = i;phi[i] = i-1;}for(int j = 1; j <= prime_num && i*prime[j] <= maxn; j++){flag[i*prime[j]] = 1;if(i % prime[j] == 0)phi[i*prime[j]] = phi[i] * prime[j];else phi[i*prime[j]] = phi[i] * (prime[j]-1);}}}int Eular(int n){if(n < maxn)return phi[n] % p;//求大于maxn的Eular(n)int res = n;for(int i = 1; prime[i]*prime[i] <= n && i <= prime_num; i++){if(n % prime[i] == 0){res -= res/prime[i];while(n%prime[i] == 0)n = n/prime[i];}}if(n > 1)res -= res/n;return res%p;}int main(){int test;get_prime();scanf("%d",&test);while(test--){scanf("%d %d",&n,&p);ans = 0;for(int l = 1; l*l <= n; l++){if(l*l == n){ans = (ans + Eular(l)*mod_exp(n,l-1,p))%p;}else if(n%l == 0) //循环节长度为l,那么n/l也是循环节长度{ans = (ans + Eular(l)*mod_exp(n,n/l-1,p))%p;ans = (ans + Eular(n/l)*mod_exp(n,l-1,p))%p;}}printf("%d\n",ans);}return 0;}
0 0
- poj 2154 Color(polya计数 + 欧拉函数优化)
- Poj 2154 Color (Polya计数 欧拉函数优化)
- [ACM] POJ 2154 Color (Polya计数优化,欧拉函数)
- poj 2154 Color polya计数+欧拉优化
- POJ 2154 Color Polya计数法+欧拉函数
- POJ 2154 Color Polya(Polya定理+欧拉函数)
- POJ 2154 Color Polya定理+欧拉函数优化 -
- poj 2154 Color Polya定理 欧拉函数优化
- POJ 2154 Color Polya定理+欧拉函数优化
- poj 2154 Color(欧拉函数+Polya)
- POJ 2154 Color (polya 欧拉函数)
- poj 2154 Color(polya + 欧拉函数)
- POJ 2154 Color (Polya定理+欧拉函数)
- POJ 2154 Color (Polya + 欧拉函数)
- POJ 2154 Color(polya定理+欧拉函数)
- POJ 2154 color(欧拉函数,Polya定理)
- poj 2154 Color 欧拉函数优化的ploya计数
- POJ 2154 Color polya计算+欧拉优化
- POJ 1258-Agri-Net (Kruskal)
- Linux文件系统
- postgres 之 initdb 源码分析 六
- 实用小命令
- iOS 中用UIView来实现动画效果
- poj 2154 Color(polya计数 + 欧拉函数优化)
- 详细总结 Hive VS 传统关系型数据库
- 计算字符个数
- 01 最大子序列求和
- Android自定义组件系列【8】——遮罩文字动画
- PHP获取各大网站上的你想要的高质量妹子图
- 一个简单的带缓存http代理
- HDU 4587 TWO NODES(无向图割点)
- Git Push 避免用户名和密码方法