zoukankan      html  css  js  c++  java
  • 【洛谷P4708】—画画(Burnside引理)

    传送门

    好像暴力枚举拆分解异或方程就可以过

    首先显然的一个联通块内所有点度数都是偶数

    首先显然要枚举循环拆分
    考虑对于一个循环,内部连边
    如果循环大小xx为偶数
    那么有x/2x/2种方案,其中有一种(对角线)的所有等价的连边会改变所有点的奇偶性
    其余不改变
    为奇数的话则不会改变

    考虑循环外的连边
    显然大小为x,yx,y的2个循环会有xy/lcm(x,y)=gcd(x,y)x*y/lcm(x,y)=gcd(x,y)种等价类
    每个等价类中
    xx每个点连了y/gcd(x,y)y/gcd(x,y)yy每个点连了x/gcd(x,y)x/gcd(x,y)条边
    分别考虑x,yx,y的奇偶性
    如果都为偶数则不影响
    如果一个为奇数,则相当于给那个循环一次改变所有点奇偶性的机会
    如果都为偶数,则相当于可以把2个循环奇偶性一起改变的机会

    考虑现在问题是,我们有一些点和一些边
    对于每个点有a[i]a[i]次机会改变奇偶性
    对于每个边有b[j]b[j]次机会改变2点奇偶性
    问方案数

    考虑对于每个连通块分别计算
    假设总共有aa次点,bb次边,连通块大小为nn
    那么总共方案数就是2a1+b(n1)2^{a-1+b-(n-1)}
    考虑对于任意一种生成树
    对于点,前面每次任意,最后一次由于点操作必须为偶数次
    (否则图的度数就不是偶数了)所以是确定的
    对于任意非树边任意且点确定的情况
    树边有且仅有一种方案对应
    所以是对的

    特判一下a=0a=0的时候

    #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++;
    }
    #define gc getchar
    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>
    cs int mod=998244353;
    inline int add(int a,int b){return (a+=b)>=mod?a-mod:a;}
    inline int dec(int a,int b){return (a-=b)<0?a+mod:a;}
    inline int mul(int a,int b){return 1ll*a*b%mod;}
    inline void Add(int &a,int b){(a+=b)>=mod?a-=mod:0;}
    inline void Dec(int &a,int b){(a-=b)<0?a+=mod:0;}
    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);}
    inline void chemx(int &a,int b){a<b?a=b:0;}
    inline void chemn(int &a,int b){a>b?a=b:0;}
    cs int N=66;
    int fac[N],ifac[N],inv[N],gcd[N][N],cnt[N];
    int n,ans;
    vector<int> divi;
    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-1]=Inv(fac[N-1]);
    	for(int i=N-2;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 fa[N],val[N];
    inline int find(int x){
    	return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    inline void calc(){
    	int coef=fac[n],tot=0;
    	for(int i=1;i<=n;i++)Mul(coef,ifac[cnt[i]]);
    	for(int &x:divi)Mul(coef,inv[x]);
    	int siz=divi.size();
    	for(int i=0;i<siz;i++)fa[i]=i,val[i]=0;
    	for(int i=0;i<siz;i++){
    		int x=divi[i];
    		tot+=(x-1)/2;
    		if((x&1)==0)val[i]++;
    	}
    	for(int i=0;i<siz;i++)
    	for(int j=i+1;j<siz;j++){
    		int g=gcd[divi[i]][divi[j]];
    		int x=(divi[i]/g)&1,y=(divi[j]/g)&1;
    		if(x+y==2){
    			int f1=find(i),f2=find(j);
    			if(f1!=f2)fa[f1]=f2;tot+=g;
    		}
    		else if(x+y==0)tot+=g;
    		else if(x==1)val[j]+=g;
    		else val[i]+=g;
    	}
    	for(int i=0;i<siz;i++)
    		if(find(i)!=i)val[find(i)]+=val[i];
    	for(int i=0;i<siz;i++)
    	if(find(i)==i){
    		tot+=val[i]?val[i]-1:0,tot++;
    	}tot-=siz;
    	Add(ans,mul(coef,ksm(2,tot)));
    }
    void dfs(int res,int mx){
    	if(!res)return calc();
    	if(res<mx)return;
    	for(int i=mx;i<=res;i++)
    	cnt[i]++,divi.pb(i),dfs(res-i,i),cnt[i]--,divi.pop_back();
    }
    inline int Gcd(int a,int b){
    	return b?Gcd(b,a%b):a;
    }
    int main(){
    	init();
    	n=read();
    	for(int i=1;i<=n;i++)
    	for(int j=1;j<=n;j++)gcd[i][j]=Gcd(i,j);
    	dfs(n,1);
    	cout<<mul(ifac[n],ans);
    }
    
  • 相关阅读:
    表单提交方式
    js--dom对象
    js--bom对象
    css布局的漂浮、position定位
    python语法学习第五天--lambda表达式、filter()、map()
    python语法学习第五天--函数(2)
    python3语法学习第五天--函数(1)
    python3语法学习第四天--序列
    leetcode| 84. 柱状图中最大的矩形
    leetcode| 56. 合并区间
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328537.html
Copyright © 2011-2022 走看看