Burnside引理和Polya定理相关题集

题目链接

LCS HDU-5495

题意

给两个序列:\(\{a_1,a_2,\cdots,a_n\}\)\(\{b_1,b_2,\cdots,b_n\}\) ,都是 \(\{1,2,3,\cdots,n \}\) 的一个排列。求出一个序列 \(p\) ,使得 \(a_{p_1},a_{p_2},\cdots,a_{p_n}\)\(b_{p_1},b_{p_2},\cdots,b_{p_n}\)\(\text{LCS}\) 最大。输出该 \(\text{LCS}\) 的值。

分析

\(a_i->b_i\) 建边,最终总能形成一个环,对于这个长度为 \(L\) 的环,我们总能找到一个长度为 \(L-1\)\(\text{LCS}\)。所以,我们只要用序列的长度减去长度大于 \(1\) 的环的个数就是最终的结果。

代码

#include <bits/stdc++.h>

using namespace std;
const int N=1e5+5;
int a[N],nxt[N];
bool vis[N];
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        int ans=0,b;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            vis[i]=0;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&b);
            nxt[a[i]]=b;
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[a[i]])
            {
                int x=a[i],cnt=0;
                while(!vis[x])
                {
                    vis[x]=1;
                    x=nxt[x];
                    cnt++;
                }
                ans+=cnt;//cout<<"cnt="<<cnt<<endl;
                if(cnt>1) ans--;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

Count the Tetris HDU-1812

Let it Bead POJ-2409

题意

给出 \(c\) 种颜色的珍珠,每种的数量无限,组成长为 \(s\) 的项链。问可以组成多少种不同的项链。\(cs\leq 32\)

分析

Polya定理模板题,直接套公式。设 \(\{a_1,a_2,\cdots,a_{|G|} \}\)\({1,2,\cdots,n}\) 上的置换群,现用 \(m\) 种颜色对这 \(n\) 个点染色,则不同的染色方案有:

\[ANS=\frac{(m^{c_1}+m^{c_2}+\cdots+m^{c_{|G|}})}{|G|} \]

其中,\(c_k\) 为置换 \(a_k\) 中轮换的个数,即循环节的个数。

常见置换的轮换个数

  • 旋转:\(n\) 个点顺时针旋转 \(i\) 个位置的置换,轮换的个数为:\(gcd(i,n)\)
  • 翻转:\(n\) 为偶数且对称轴不过顶点:\(\frac{n}{2}\)\(n\) 为偶数且对称轴过顶点:\(\frac{n}{2}+1\)\(n\) 为奇数:\(\frac{n+1}{2}\)

代码

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long ll;
int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}
ll power(ll a,int b)
{
    ll res=1;
    while(b)
    {
        if(b&1) res=res*a;
        a=a*a;
        b>>=1;
    }
    return res;
}
int main()
{
    int c,s;
    while(scanf("%d%d",&c,&s)!=EOF)
    {
        if(c==0&&s==0) break;
        if(c==0||s==0) printf("0\n");
        ll ans=0;
        int m=2*s;
        for(int i=1;i<=s;i++)
            ans+=power(1LL*c,gcd(i,s));
        if(s&1)
            ans+=1LL*s*power(1LL*c,(s+1)/2);
        else
        {
            ans+=1LL*s/2*power(1LL*c,s/2);
            ans+=1LL*s/2*power(1LL*c,s/2+1);
        }
        printf("%lld\n",ans/m);
    }
    return 0;
}

Necklace of Beads POJ-1286

分析

模板题,同上。

Color POJ-2154

posted @ 2021-02-20 10:22  xzx9  阅读(95)  评论(0编辑  收藏  举报