POJ2154 Color polya定理+欧拉定理

由于这是第一天去实现polya题,所以由易到难,先来个铺垫题(假设读者是看过课件的,不然可能会对有些“显然”的地方会看不懂):

POJ1286 Necklace of Beads :有三种颜色,问可以翻转,可以旋转的染色方案数,n<24。

1,n比较小,恶意的揣测出题人很有可能出超级多组数据,所以先打表。

2,考虑旋转:

for(i=0;i<n;i++)  sum+=pow(n,gcd(n,i));  

3,考虑翻转:

if(n&1)  sum+=n*pow(3,n/2+1) ;
else {
      sum+=n/2*pow(3,n/2) ;
      sum+=n/2*pow(3,n/2+1) ;
} 

4,除以总置换数(n+n/2+n/2):

sum/=(2*n);

5,终极代码:

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
#define ll long long
ll ans[30];
ll gcd(ll a,ll b) {  if(b==0) return a;  return gcd(b,a%b); }
ll pow(ll a,ll x)
{
    ll res=1;
    while(x){
        if(x&1) res*=a;
        x>>=1;
        a*=a;
    } return res;
}
int main()
{
    ll n,i,sum;
    for(n=1;n<=23;n++){
        sum=0;
        for(i=0;i<n;i++) sum+=pow(3,gcd(n,i));
        if(n&1)  sum+=n*pow(3,n/2+1) ;
        else {
            sum+=n/2*pow(3,n/2) ;
            sum+=n/2*pow(3,n/2+1) ;
        }
        ans[n]=sum/n/2;
    }
    while(~scanf("%lld",&n)){
        if(n==-1) return 0;
        printf("%lld\n",ans[n]);
    }
    return 0;
}

----------------------------------------------------分界线--------------------------------------------------------------------------------

POJ2154 Color: 求可以旋转,不可以翻转的置换,n个珠子,n种颜色,答案mod K,n<1e9。

那么本题只考虑旋转,则:

for(i=0;i<n;i++)  ans+=pow(n,gcd(n,i));
ans/=n;

之前莫比乌斯那里,我们常用技巧是合并。  这里考虑gcd相同的合并。(做多了还是有点灵感滴,yeah)。

得到:

解决这个公式需要:快速幂+欧拉公式+一些素数的常识。

1,快速幂不说了,注意先模运算。

2,欧拉公式,枚举L,即n的素因子,然后根据phi=L*(1-1/p1)*(1-1/p2)...得到欧拉函数。

3,素数常识,在这里指的是一个数n的素因子最多有一个大于根号n,所以一直除,把根号n前的素数都除完了,留下的一定是大于根号n的一个素数。

//可以线筛一部分欧拉函数出来,不够的再枚举素数;枚举的话不超过根号个,所以复杂度不会太高。
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=100000;
int ans, Mod;
int pri[maxn+10],cnt,vis[maxn+10],phi[maxn+10];
int qpow(int a,int x)
{
    int res=1;a%=Mod;//这里a一定要除一下,不然会超int,猪啊。
    while(x){
        if(x&1) res=res*a%Mod;
        x>>=1; a=a*a%Mod;
    } return res%Mod;
}
void prime()
{
    phi[1]=1;
    for(int i=2;i<=maxn;i++){
        if(!vis[i]) pri[++cnt]=i,phi[i]=i-1;
        for(int j=1;j<=cnt&&pri[j]*i<=maxn;j++) {
            vis[pri[j]*i]=1;
            if(i%pri[j]==0) {
                phi[i*pri[j]]=phi[i]*pri[j];
                break;
            }
            else phi[i*pri[j]]=phi[i]*(pri[j]-1);
        }
    }
}
int Phi(int x)
{
    if(x<=maxn) return phi[x]%Mod;
    int res=x;
    for(int i=1;pri[i]*pri[i]<=x;i++)
      if(x%pri[i]==0){
          res=(res-res/pri[i]);
          while(x%pri[i]==0) x/=pri[i];
     }
    if(x!=1) res=(res-res/x);
    return res%Mod;
}
int main()
{
    int n,T; prime();
    scanf("%d",&T);
    while(T--){
        ans=0; scanf("%d%d",&n,&Mod);
        for(int i=1;i*i<=n;i++){
            if(n%i!=0) continue;
            ans=(ans+qpow(n,i-1)*Phi(n/i))%Mod;
            if(i*i!=n) ans=(ans+qpow(n,n/i-1)*Phi(i))%Mod;
        }
        printf("%d\n",ans);
    } return 0;
}

原文地址:https://www.cnblogs.com/hua-dong/p/8418430.html

时间: 2024-08-02 18:51:27

POJ2154 Color polya定理+欧拉定理的相关文章

POJ2154 Color(Polya定理)

Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 11654   Accepted: 3756 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 nec

【poj2154】Color Polya定理+欧拉函数

题目描述 $T$ 组询问,用 $n$ 种颜色去染 $n$ 个点的环,旋转后相同视为同构.求不同构的环的个数模 $p$ 的结果. $T\le 3500,n\le 10^9,p\le 30000$ . 题解 Polya定理+欧拉函数 根据 poj2409 中得到的结论,答案为: $\frac{\sum\limits_{i=1}^nn^{\gcd(i,n)}}n=\sum\limits_{i=1}^nn^{\gcd(i,n)-1}$ 由于 $n$ 有 $10^9$ 之大,因此考虑优化这个式子. 枚举

[POJ1286&amp;POJ2154&amp;POJ2409]Polya定理

Polya定理 L=1/|G|*(m^c(p1)+m^c(p2)+...+m^c(pk)) G为置换群大小 m为颜色数量 c(pi)表示第i个置换的循环节数 如置换(123)(45)(6)其循环节数为3 ------------------------------------------------------------------------------------------- POJ1286&POJ2409 都是简单的处理串珠子的问题. 题目中隐藏着3种不同的置换类别. 1.旋转 注意不

POJ2154 Color【Polya定理】【欧拉函数】【整数快速幂】

题目链接: http://poj.org/problem?id=2154 题目大意: 给定 N 种颜色的珠子,每种颜色珠子的个数均不限,将这些珠子做成长度为 N 的项链. 问能做成多少种不重复的项链,最后结果对 P 取模.并且两条项链相同,当且仅当两条 项链通过旋转后能重合在一起,且对应珠子的颜色相同. 解题思路: Polya定理的应用.先来看Polya定理. Polya定理:设 G = {a1,a2,-,ag}是 N 个对象的置换群,用 M 种颜色给这 N 个 对象着色,则不同的着色 方案数为

置换群和Burnside引理,Polya定理

定义简化版: 置换,就是一个1~n的排列,是一个1~n排列对1~n的映射 置换群,所有的置换的集合. 经常会遇到求本质不同的构造,如旋转不同构,翻转交换不同构等. 不动点:一个置换中,置换后和置换前没有区别的排列 Burnside引理:本质不同的方案数=每个置换下不动点的个数÷置换总数(一个平均值) Polya定理:一个置换下不动点的个数=颜色^环个数.(辅助Burnside引理,防止枚举不动点复杂度过高) 这篇文章写得很详细了(具体的在此不说了): Burnside引理与Polya定理 **特

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加法下是一个群. 群元素的个数有限,称为有限群,且其中元素的个数称为

POJ_2409 Let it Bead(Polya定理)

描述 "Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. As you can deduce from the company name, their business is beads. Their PR department found out that customers are interested in buying colored bracelets. However,

Burnside引理与Polya定理

Burnside引理与Polya定理 Burnside引理与Polya定理是有关组合数学的两条十分重要的定理(引理),但是网上的一些资料大多晦涩难懂或者与实际并不相关联,因此在这里做一些浅显的解读,希望通过此文章可以让这两条定理(引理)能够发挥其作用. PS:引理与定理的区别: Ψ引理是数学中为了取得某个更好的定理而作为步骤被证明的命题,其意义并不在于自身被证明,而在于为达成最终定理作出贡献. Ψ一个引理可用于证明多个定理.数学中存在很多著名的引理,这些引理可能对很多问题的解决有帮助.例如欧几里

[POJ2409]Let it Bead - Polya定理

[POJ2409]Let it Bead Time Limit: 1000MS   Memory Limit: 65536K Description "Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. As you can deduce from the company name, their business is beads. Their PR department found