poj 2154 Color(欧拉函数,快速幂,波利亚计数)
来源:互联网 发布:程序员的思维方式 编辑:程序博客网 时间:2024/05/18 00:06
Color
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 7458 Accepted: 2452
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.
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
本题只考虑旋转,不考虑翻转,因此置换群大小为N!ans = [N^gcd(1,N)+N^gcd(2,N)...+N^gcd(N,N)]/N;
=>ans = N^(gcd(1,N)-1)+N^(gcd(2,N)-1)...+N^(gcd(N,N)-1)这个时候我们就可以在运算时%P了。
难点1:如何提高求gcd(i,N)的效率?
我们知道,如果用暴力的话肯定是超时的,因为N<=1000000000!
但是,gcd(i,N)的数量是很少的,我们可以枚举,怎么枚举呢?只要枚举从[1,sqrt(N)]就行了,因为求出所有i∈[1,sqrt(N)]能够满足N%i==0,就可以求出所有j∈[sqrt(N),N]能够满足N%j==0,j=N/i。
这样枚举的效率是sqrt(N)。ans = ∑sum[L]*N^(L-1),sum[L]为gcd(i,N)==L的个数。
难点2:如何求出gcd(i,N)==L时,i的个数?
i=L*x , N=L*y,因为gcd(i,N)==L,所以x,y互质。反证法,如果x,y不互质,则gcd(i,N)!=L。
因此,枚举L就可以求出y,然后求[1,y]与y互质的个数,这个可以用欧拉函数解决!
欧拉函数的效率小于是sqrt(y)*log2(y).
难点3:如何求N^(gcd(i,N)-1)?
如果用库函数pow会有精度损失,这肯定是不行的,如果自己用暴力写肯定会超时的,因为gcd(i,N)最大是1000000000。
所以我们用快速幂求,效率是log2(N)<30.
卡过!
#include <iostream>#include <cstdio>using namespace std;#define ll long longll N , P;ll pow(ll C , ll t){//快速幂求C^tll ans = 1;while(t>0){if(t%2==1){ans = (ans*C)%P;}C = (C%P*(C%P))%P;t /= 2;}return ans%P;}ll Euler(int x){ll ans = 1;for(int i = 2; i*i <= x; i++){if(x%i == 0){ans = ans*(i-1)%P;x /= i;while(x%i==0){ans = ans*i%P;x /= i;}}}if(x > 1) ans = (ans%P)*((x-1)%P);return ans;}ll Polya(int Bean , int Color){//波利亚计数,Bean表示项链珠子个数,Color表示颜色种数ll ans = 0;for(int i = 1; i*i <= Bean; i++){if(Bean%i == 0){if(i != Bean/i){ans += (Euler(i)%P*pow(Color , Bean/i-1)%P)%P;ans += (Euler(Bean/i)%P*pow(Color , i-1)%P)%P;}else{ans += (Euler(i)%P*pow(Color , Bean/i-1)%P)%P;}ans = ans%P;}}return ans%P;}int main(){int T;cin >> T;while(T--){scanf("%lld%lld" , &N , &P);printf("%lld\n" , Polya(N , N));}return 0;}
0 0
- poj 2154 Color(欧拉函数,快速幂,波利亚计数)
- POJ 2154 Color(组合数学-波利亚计数,数论-欧拉函数,整数快速幂)
- POJ - 2154 Color(波利亚计数)(欧拉函数)
- poj 2154 Color(polya计数 + 欧拉函数优化)
- Poj 2154 Color (Polya计数 欧拉函数优化)
- poj 2154 Color 欧拉函数优化的ploya计数
- POJ 2154 Color Polya计数法+欧拉函数
- poj 2154 Color 波利亚定理 欧拉函数 快速幂 线性筛
- [ACM] POJ 2154 Color (Polya计数优化,欧拉函数)
- poj 2154 Color polya计数+欧拉优化
- poj 2154 Color(欧拉函数+Polya)
- POJ 2154 Color (ploya欧拉函数)
- POJ 2154 Color (polya 欧拉函数)
- poj 2154 Color(polya + 欧拉函数)
- POJ 2154 Color (Polya定理+欧拉函数)
- poj 2154 Color(欧拉函数模板+ploya定理)
- POJ 2154 Color (Polya + 欧拉函数)
- POJ 2154 Color Polya(Polya定理+欧拉函数)
- 关于SPI总线学习文章
- 互联网产品设计:产品需求管理之需求收集
- MATLAB调用C/C++函数的方法
- 配置activeMQ
- C#中调用Windows API的要点
- poj 2154 Color(欧拉函数,快速幂,波利亚计数)
- 九度题目1009:二叉搜索树
- 数据架构及storm机制小结
- java读取Properties文件六种方法
- 如果常流泪,就不能看见星光
- mysql 触发器实现需求
- 为注解增加属性 和 高级属性
- x=x&(x-1)
- 《越南外资企业挂国旗自保 当地暴民烧错新加坡旗》