POJ2888 Magic Bracelet

Description

Ginny’s birthday is coming soon. Harry Potter is preparing a birthday present for his new girlfriend. The present is a magic bracelet which consists of n magic beads. The are m kinds of different magic beads. Each kind of beads has its unique characteristic. Stringing many beads together a beautiful circular magic bracelet will be made. As Harry Potter’s friend Hermione has pointed out, beads of certain pairs of kinds will interact with each other and explode, Harry Potter must be very careful to make sure that beads of these pairs are not stringed next to each other.

There infinite beads of each kind. How many different bracelets can Harry make if repetitions produced by rotation around the center of the bracelet are neglected? Find the answer taken modulo 9973.

Solution

使用burnside引理,考虑每一个置换的不动点个数

循环节个数为$d$的置换共有$\varphi (\frac nd)$个,所以可以在$O(\sqrt n)$内枚举每一种情况

如果一个置换循环节有$x$个,那么它的颜色排列可以转化为长度为$x$的环上的所有颜色排列情况

做出颜色可否相邻的邻接矩阵,用矩阵快速幂求解情况数

略卡常

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int T,n,m,k,lim;
long long ans;
const long long mod=9973;
struct Matrix
{
    int a[12][12];
    void clear()
    {
        memset(a,0,sizeof(a));
    }
    Matrix operator * (const Matrix &z)const
    {
        Matrix ret;
        ret.clear();
        for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) for(int k=1;k<=m;k++) ret.a[i][j]+=a[i][k]*z.a[k][j];
        for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) ret.a[i][j]%=mod; 
        return ret;
    }
}O,M;
inline int read()
{
    int f=1,w=0;
    char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
    return f*w;
}
long long phi(int x)
{
    long long ret=x;
    for(int i=2;i*i<=x;i++)
    {
        if(!(x%i))
        {
            ret-=ret/i;
            while(!(x%i)) x/=i;
        }
    }
    if(x!=1) ret-=ret/x;
    return ret%mod;
}
long long ksm(long long a,long long p)
{
    long long ret=1;
    a%=mod;
    while(p)
    {
        if(p&1) (ret*=a)%=mod;
        p>>=1,(a*=a)%=mod;
    }
    return ret;
}
Matrix ksm(Matrix A,int p)
{
    Matrix ret=O;
    while(p)
    {
        if(p&1) ret=ret*A;
        A=A*A,p>>=1;
    }
    return ret;
}
long long calc(int x)
{
    Matrix temp=ksm(M,x);
    long long ret=0;
    for(int i=1;i<=m;i++) (ret+=temp.a[i][i])%=mod;
    return ret;
}
int main()
{
    T=read();
    for(int i=1;i<=10;i++) O.a[i][i]=1; 
    for(;T;T--)
    {
        n=read(),m=read(),k=read(),lim=floor(sqrt(n)),ans=0;
        for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) M.a[i][j]=1;
        for(int i=1;i<=k;i++)
        {
            int x=read(),y=read();
            M.a[x][y]=M.a[y][x]=0;
        }
        for(int i=1;i<=lim;i++) if(!(n%i))
        {
            (ans+=phi(n/i)*calc(i)%mod)%=mod;
            if(i*i!=n) (ans+=phi(i)*calc(n/i)%mod)%=mod;
        }
        printf("%lld\n",ans*ksm(n,mod-2)%mod);
    }
    return 0;
}
Magic Bracelet

 

posted @ 2021-01-21 11:05  QDK_Storm  阅读(70)  评论(0编辑  收藏  举报