• 【CodeChef】—Sum of Cubes(斯特林数+容斥+三元环计数)


    传送门


    fs,if_{s,i}表示边ii在点集ss中是否出现

    答案就是s(ifs,i)ksum_{s}(sum_{i}f_{s,i})^k

    考虑把kk次方拆开就是i=0kSk,ii!(fs,ii)sum_{i=0}^{k}S_{k,i}i!{sum_{f_{s,i}}choose i}

    考虑这个式子的组合意义,就是把一个置换的所有循环的集合的所有子集选出来
    一个大小为ii的子集的贡献就是Sk,ii!S_{k,i}i!

    就只需要把所有大小在kk以内的集合贡献求出来
    考虑一个边的集合只需要考虑有哪些点必须选
    剩下随便选或不选

    一条边和两条边很好求
    主要3条边
    有5种情况
    1、AB,CD,EFA-B,C-D,E-F
    2、ABC,DEA-B-C,D-E
    3、ABCDA-B-C-D
    4、AB,AC,ADA-B,A-C,A-D
    5、ABCAA-B-C-A

    5要用到三元环计数
    然后依次推4、3、2、1,中间要容斥一下

    然后就完了

    #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 pob pop_back
    #define cs const
    #define poly vector<int>
    cs int mod=1e9+7;
    inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
    inline void Add(int &a,int b){a=add(a,b);}
    inline int dec(int a,int b){return a>=b?a-b:a-b+mod;}
    inline void Dec(int &a,int b){a=dec(a,b);}
    inline int mul(int a,int b){return 1ll*a*b>=mod?1ll*a*b%mod:a*b;}
    inline void Mul(int &a,int b){a=mul(a,b);}
    inline int ksm(int a,int b,int res=1){for(;b;b>>=1,a=mul(a,a))(b&1)?(res=mul(res,a)):0;return res;}
    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=100005;
    int s[4][4];
    inline void init(){
    	s[0][0]=1;
    	for(int i=1;i<=3;i++)
    	for(int j=1;j<=3;j++)
    	s[i][j]=add(s[i-1][j-1],mul(s[i-1][j],j));
    }
    inline ll C3(int n){
    	return 1ll*(n-1)*(n-2)*n/6;
    }
    vector<int> e[N];
    int n,m,k,in[N];
    inline int solve1(){
    	if(n>=2)return mul(m,mul(ksm(2,n-2),s[k][1]));
    	else return 0;
    }
    inline int solve2(){
    	ll tot=0;int res=0;
    	for(int i=1;i<=n;i++)
    	for(int &v:e[i])tot+=in[v]-1;
    	tot/=2;
    	if(n>=3)Add(res,mul(tot%mod,mul(ksm(2,n-3),s[k][2])));
    	tot=1ll*m*(m-1)/2-tot;
    	if(n>=4)Add(res,mul(tot%mod,mul(ksm(2,n-4),s[k][2])));
    	return mul(res,2);
    }
    int cnt[N];
    inline bool comp(int u,int v){
    	return (in[u]==in[v])?u>v:in[u]>in[v];
    }
    inline ll calc2(){
    	ll res=0;
    	for(int i=1;i<=n;i++)
    	res+=1ll*in[i]*(in[i]-1)/2*(m-2);
    	return res;
    }
    inline ll calc3(){
    	ll res=0;
    	for(int i=1;i<=n;i++)
    	for(int &v:e[i])
    	res+=1ll*(in[i]-1)*(in[v]-1);
    	return res/2;
    }
    inline ll calc4(){
    	ll res=0;
    	for(int i=1;i<=n;i++)
    	res+=C3(in[i]);
    	return res;
    }
    inline ll calc5(){
    	ll res=0;
    	for(int u=1;u<=n;u++){
    		for(int &v:e[u])if(comp(u,v))cnt[v]++;
    		for(int &v:e[u])if(comp(u,v))
    		for(int &z:e[v])if(comp(v,z))
    		if(cnt[z])res++;
    		for(int &v:e[u])if(comp(u,v))cnt[v]=0;
    	}
    	return res;
    }
    inline int solve3(){
    	ll cnt1=0,cnt2=0,cnt3=0,cnt4=0,cnt5=0;
    	cnt5=calc5(),cnt4=calc4(),cnt3=calc3()-cnt5*3;
    	cnt2=calc2()-cnt4*3-cnt5*3-cnt3*2,cnt1=C3(m)-cnt2-cnt3-cnt4-cnt5;
    	cnt1%=mod,cnt2%=mod,cnt3%=mod,cnt4%=mod,cnt5%=mod;
    	int res=0;
    	if(cnt1)Add(res,mul(cnt1,ksm(2,n-6)));
    	if(cnt2)Add(res,mul(cnt2,ksm(2,n-5)));
    	if(cnt3)Add(res,mul(cnt3,ksm(2,n-4)));
    	if(cnt4)Add(res,mul(cnt4,ksm(2,n-4)));
    	if(cnt5)Add(res,mul(cnt5,ksm(2,n-3)));
    	return mul(res,mul(s[k][3],6));
    }
    inline void solve(){
    	n=read(),m=read(),k=read();int res=0;
    	for(int i=1;i<=m;i++){
    		int u=read(),v=read();
    		in[u]++,in[v]++;
    		e[u].pb(v),e[v].pb(u);
    	}
    	if(1<=k)Add(res,solve1());
    	if(2<=k)Add(res,solve2());
    	if(3<=k)Add(res,solve3());
    	cout<<res<<'
    ';
    	memset(in,0,sizeof(int)*(n+1));
    	for(int i=1;i<=n;i++)e[i].clear();
    }
    int main(){
    	init();
    	int T=read();
    	while(T--)solve();
    }
    
  • 相关阅读:
    vscode安装扩展插件提示:扩展不可用,XHR error?
    react函数组件的条件渲染和列表渲染
    动态设置背景图片和图片地址
    computed和watch,getters的计算变化
    VueLazyLoad图片懒加载
    vuex实现数据持久化
    vuex不需要一个个引入模块文件
    react的state和setState
    热爱生命 汪国真
    分分钟手写http server
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328636.html
Copyright © 2020-2023  润新知