HDU2481:Toy(Burnside)

来源:互联网 发布:新疆棉花加工数据 编辑:程序博客网 时间:2024/06/08 09:09

传送门

题意:
外面有一圈N个结点,中心有一个结点与N个结点都相连,总共就是2*N条边,删除N条边,使N+1个点连通,旋转相同视为等价,问有多少种情况。

题解:
Burnside引理。

首先枚举公约数,找等价类。
对于一个等价类,矩阵树+打表发现f(n)=3f(n1)f(n2)+2,直接矩阵快速幂。

要注意的是mod一个合数可能不存在逆元,稍加转化:

a=(kc+r)babmodc=ramodbcb=r

O(1)快速乘就好了:http://blog.csdn.net/qq_35649707/article/details/76732760

#include<iostream>#include<cstdio>using namespace std;struct IO{    streambuf *ib,*ob;    inline void init(){        ios::sync_with_stdio(false);        cin.tie(NULL);cout.tie(NULL);        ib=cin.rdbuf();ob=cout.rdbuf();    }    template<typename T1>    inline bool read(T1 &x){        static char ch;static long long i,f;        ch=ib->sbumpc();i=0,f=1;        while(!isdigit(ch)){            if(ch==-1)return false;            if(ch=='-')f=-1;            ch=ib->sbumpc();        }        while(isdigit(ch)){            i=(i+(i<<2)<<1)+ch-'0';            ch=ib->sbumpc();        }        x=((f>0)?i:-i);        return true;    }    inline void W(long long x){        static long long buf[50];        if(!x){ob->sputc('0');return;}        if(x<0){ob->sputc('-');x=-x;}        while(x){buf[++buf[0]]=x%10;x/=10;}        while(buf[0]){ob->sputc(buf[buf[0]--]+'0');}    }}io;long long n;long long mod;long long ans;inline long long mul(long long x,long long y){    return (x*y-(long long)((long double)x/mod*y)*mod+mod)%mod;  }struct matrix{    long long a[4][4];    inline void init(long long val){        for(long long i=1;i<=3;i++)            for(long long j=1;j<=3;j++)            this->a[i][j]=0;        for(long long i=1;i<=3;i++)this->a[i][i]=val;    }    friend inline matrix operator *(const matrix &a,const matrix &b)    {        matrix c;c.init(0);        for(long long i=1;i<=3;i++)            for(long long j=1;j<=3;j++)                for(long long k=1;k<=3;k++)                    (c.a[i][j]+=mul(a.a[i][k],b.a[k][j]))%=mod;        return c;    }    friend inline matrix operator ^(matrix a,long long b)    {        matrix c;c.init(1);        for(;b;b>>=1,a=a*a)        if(b&1)c=c*a;        return c;    }}e;inline long long getphi(long long x){    long long res=x;    for(long long b=2;b*b<=x;b++)    {        if(x%b)continue;        (res/=b)*=(b-1);        while(!(x%b))x/=b;    }    if(x!=1)(res/=x)*=(x-1);    return res;}inline long long calc(long long k){    if(k<3){return ((k==1)?1:5);}    matrix a;a.init(0);    a.a[1][1]=5,a.a[1][2]=1,a.a[1][3]=2;    a=a*(e^(k-2));    return a.a[1][1];}int main(){    io.init();e.init(0);    e.a[1][1]=3;e.a[1][2]=1;e.a[3][1]=1;e.a[3][3]=1;    while(io.read(n),io.read(mod)){        ans=0;mod*=n;        e.a[2][1]=mod-1;        for(long long d=1;d*d<=n;d++){            if(n%d)continue;            (ans+=(1ll*mul(getphi(n/d),calc(d))%mod))%=mod;            if(n/d!=d)(ans+=(1ll*mul(getphi(d),calc(n/d))%mod))%=mod;        }        io.W(ans/n);io.ob->sputc('\n');    }}
原创粉丝点击