• 【洛谷P4128】【SHOI2006】—有色图(Burnside)


    传送门

    看起来像要用polyapolya
    但是仔细分析发现用不了

    仔细想想发现和图的同构那道题没任何区别
    只是把颜色数从22变成了mm

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ob==ib)?EOF:*ib++;
    }
    inline int read(){
        char ch=gc();
        int res=0,f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    #define bg begin
    #define poly vector<int>  
    int mod;
    inline int add(int a,int b){return (a+=b)>=mod?a-mod:a;}
    inline void Add(int &a,int b){(a+=b)>=mod?a-=mod:0;}
    inline int dec(int a,int b){return (a-=b)<0?a+mod:a;}
    inline void Dec(int &a,int b){(a-=b)<0?a+=mod:0;}
    inline int mul(int a,int b){return 1ll*a*b%mod;}
    inline void Mul(int &a,int b){a=1ll*a*b%mod;}
    inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
    inline int Inv(int x){return ksm(x,mod-2);}
    #define chemx(a,b) ((a)<(b)?(a)=(b):0)
    #define chemn(a,b) ((a)>(b)?(a)=(b):0)
    cs int N=55;
    int n,m,ans;
    int G[N][N],cnt[N],fac[N],ifac[N],inv[N];
    vector<int> divi;
    inline int gcd(int a,int b){
    	return b?gcd(b,a%b):a;
    }
    inline void calc(){
    	int coef=fac[n];
    	for(int i=1;i<=n;i++)
    		Mul(coef,ifac[cnt[i]]);
    	for(int &x:divi)
    		Mul(coef,inv[x]);
    	int tot=0;
    	for(int &x:divi)tot+=x/2;
    	for(int i=0;i<divi.size();i++)
    	for(int j=i+1;j<divi.size();j++)
    	tot+=G[divi[i]][divi[j]];
    	Add(ans,mul(coef,ksm(m,tot)));
    }
    void dfs(int res,int last){
    	if(!res)return calc();
    	if(res<last)return;
    	for(int i=last;i<=res;i++)
    		cnt[i]++,divi.pb(i),dfs(res-i,i),divi.pop_back(),cnt[i]--;
    }
    inline void init(){
    	fac[0]=ifac[0]=inv[0]=inv[1]=1;
    	for(int i=1;i<=n;i++)fac[i]=mul(fac[i-1],i);
    	ifac[n]=Inv(fac[n]);
    	for(int i=n-1;i;i--)ifac[i]=mul(ifac[i+1],i+1);
    	for(int i=2;i<=n;i++)inv[i]=mul(mod-mod/i,inv[mod%i]);
    }
    int main(){
    	#ifdef Stargazer
    	freopen("lx.cpp","r",stdin);
    	#endif
    	n=read(),m=read(),mod=read();
    	init();
    	for(int i=1;i<=n;i++)
    	for(int j=1;j<=i;j++)
    	G[i][j]=G[j][i]=gcd(i,j);
    	dfs(n,1);
    	cout<<mul(ans,ifac[n]);
    }
    
  • 相关阅读:
    「Codeforces 79D」Password
    「算法笔记」BSGS
    「Codeforces 468C」Hack it!
    「算法笔记」快速傅里叶变换(FFT)
    「算法笔记」2-SAT 问题
    「算法笔记」基础数论 2
    《算法笔记》二分—木棒切割问题&求凸多边形外接圆最大半径
    《算法笔记》区间贪心
    《算法笔记》PAT B1020 月饼、PAT B1023 组个最小数
    《算法笔记》n皇后问题
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328481.html
Copyright © 2020-2023  润新知