其他分享
首页 > 其他分享> > 修仙录 3.25

修仙录 3.25

作者:互联网

怎么每道题都跟我没学过的公式有关。。
可惜没想出T1dp50分(改是改了)
改不动的,该前面的好了。


jzoj 6079 染色问题

https://jzoj.net/senior/#main/show/6079
想法清奇。
在这里插入图片描述
神奇。
主要讲讲最后状压dp的部分
f[i][s]:用i种颜色染s集合的方案数
转移显然,多用一种颜色,就枚举这个颜色的集合,与已经染好的构成新集合
同颜色集合权值预处理,不同颜色随dp转移就好
因为是选i种颜色,最后乘上一个CkiC_k^iCki​

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define LL long long
using namespace std;
const int MAXN=1e5+5;
const int mod=1e9+7;

int n,m,k,tot,id[MAXN],t[MAXN];
int head[MAXN],du[MAXN],cnt;
struct edge{
	int to,next;
	LL a,b;
	edge(){to=next=a=b=0;}
	edge(int to,int next,LL a,LL b):to(to),next(next),a(a),b(b){}
};
vector<edge>e,g[15];
queue<int>q;
bool isv[MAXN];
LL ans=1,val[1<<15],sum,f[15][1<<15],ml[MAXN],inv[MAXN];

void add(int u,int v,int a,int b){
	e.push_back(edge(v,head[u],a,b)),du[v]++,head[u]=++cnt;
	e.push_back(edge(u,head[v],a,b)),du[u]++,head[v]=++cnt;
}

void del_1(){
	for(int i=1;i<=n;i++) if(du[i]==1) q.push(i),isv[i]=1;
	while(!q.empty()){
		int x=q.front();q.pop();
		if(du[x]==1) ans=ans*(k-1)%mod;
		for(int i=head[x];i;i=e[i].next){
			int y=e[i].to;
			if(--du[y]==1) q.push(y),isv[y]=1;
		}
	}
}

void del_2(){
	for(int x=1;x<=n;x++){
		if(du[x]!=2) continue;
		int a=0,b=0,u,v;
		for(int i=head[x];i;i=e[i].next){
			if(isv[e[i].to]) continue;
			if(!a) a=i,u=e[i].to;
			else b=i,v=e[i].to;
		}
		if(u==v) continue;
		isv[x]=1,du[u]--,du[v]--;
		LL l_0=(e[a].a*e[b].a%mod+e[a].b*e[b].b%mod*(k-1)%mod)%mod;
		LL l_1=(e[a].a*e[b].b%mod+e[a].b*e[b].a%mod+e[a].b*e[b].b%mod*(k-2)%mod)%mod;
		add(u,v,l_0,l_1);
	}
}

LL C(int n,int m){
	return ml[n]*inv[m]%mod*inv[n-m]%mod;
}

int main(){
	freopen("color.in","r",stdin);
	freopen("color.out","w",stdout);
	cin>>n>>m>>k;e.push_back(edge(0,0,0,0));
	for(int i=1,u,v;i<=m;i++) scanf("%d%d",&u,&v),add(u,v,0,1);
	del_1(),del_2();
	for(int i=1;i<=n;i++) if(!isv[i]) t[++tot]=i,id[i]=tot;
	if(!tot){cout<<ans*k%mod;return 0;}
	for(int x=1;x<=tot;x++) for(int i=head[t[x]];i;i=e[i].next){
		int y=e[i].to;
		if(isv[y]) continue;
		g[x].push_back(edge(id[y],0,e[i].a,e[i].b));
	}
	for(int s=1;s<(1<<tot);s++){
		val[s]=1;
		for(int x=1;x<=tot;x++) if(s&(1<<x-1))
		for(int i=0;i<g[x].size();i++){
			int y=g[x][i].to;
			if(s&(1<<y-1)&&y<x) val[s]=val[s]*g[x][i].a%mod;
		}
	}
	f[0][0]=ml[0]=inv[0]=inv[1]=1;
	for(int i=1;i<=k;i++) ml[i]=ml[i-1]*i%mod;
	for(int i=2;i<=k;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
	for(int i=2;i<=k;i++) inv[i]=inv[i]*inv[i-1]%mod;
	for(int i=0;i<tot;i++){
		for(int s=0;s<(1<<tot);s++) if(f[i][s]){
			int S=((1<<tot)-1)^s;
			for(int j=S;j;j=j-1&S){
				LL now=1;
				for(int x=1;x<=tot;x++)if(j&(1<<x-1))
					for(int y=0;y<g[x].size();y++) if(s&(1<<g[x][y].to-1)) now=now*g[x][y].b%mod;
				f[i+1][j|s]=(f[i+1][j|s]+f[i][s]*now%mod*val[j]%mod)%mod;
			}
		}
		sum=(sum+f[i+1][(1<<tot)-1]*C(k,i+1)%mod)%mod;
	}
	cout<<ans*sum%mod;
	return 0;
}

jzoj 6080 IOer

https://jzoj.net/senior/#contest/show/2681/1
emmmmm
看不懂,直接粘题解。
代码还是好打的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
呵呵

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define LL long long
using namespace std;
const int MAXN=2e5+5;
const int mod=998244353;

int T;
LL n,m,u,v,ml[MAXN],inv[MAXN];

LL C(LL n,LL m){
	return ml[n]*inv[n-m]%mod*inv[m]%mod;
}

LL Pow(LL a,LL b){
	LL ans=1;
	a%=mod;
	while(b){
		if(b&1) ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans;
}

LL calc(){
	LL ans=0;
	for(int i=0;i<m;i++){
		LL now=C(m-1,i)*Pow((m-i)*u+v,n+m-1)%mod;
		if(i%2) now=(-now+mod)%mod;
		ans=(ans+now)%mod;
	}
	return ans*inv[m-1]%mod*Pow(Pow(u,m-1),mod-2)%mod;
}

int main(){
	freopen("ioer.in","r",stdin);
	freopen("ioer.out","w",stdout);
	cin>>T;ml[0]=inv[0]=inv[1]=1;
	for(int i=1;i<=2e5;i++) ml[i]=ml[i-1]*i%mod;
	for(int i=2;i<=2e5;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
	for(int i=2;i<=2e5;i++) inv[i]=inv[i]*inv[i-1]%mod;
	while(T--){
		cin>>n>>m>>u>>v;
		cout<<calc()<<endl;
	}
	return 0;
}

标签:int,LL,修仙,3.25,ans,MAXN,include,mod
来源: https://blog.csdn.net/qq_41709770/article/details/88802235