2018.10.25 uoj#308. 【UNR #2】UOJ拯救计划(排列组合)

该博客探讨了一道编号为UNR #2的UOJ问题,涉及排列组合在数学问题中的应用。博主指出,解决这个问题的关键在于注意到模6的性质,当i大于等于3时,A(n,i)对6取模的结果为0。因此,重点在于计算i等于1和2的情况。同时,博主提到了题目中可能存在的误导,如m的取值未明确限制和边数描述的不一致,对解题思路的影响。" 130213280,5751841,华为OD机试:完美走位算法解析及代码实现,"['算法', '开发语言', 'Python', 'Java', 'JavaScript']
摘要由CSDN通过智能技术生成

传送门
有一个显然的式子: A n s = ∑ A ( n , i ) ∗ 用 i 种 颜 色 的 方 案 数 Ans=\sum A(n,i)*用i种颜色的方案数 Ans=A(n,i)i
这个东西貌似是个 N P C NPC NPC
于是需要仔细观察数据范围。
咦模数等于 6 6 6
那么对于 A ( n , i ) A(n,i) A(n,i) i ≥ 3 i\geq 3 i3的时候模 6 6 6都是 0 0 0了。
因此只用讨论 i = 1 i=1 i=1 i = 2 i=2 i=2的方案数。
什么?
i = 1 ? i=1? i=1?
没错,题目上并没有说过 m ! = 0 m!=0 m!=0啊。
还有就是貌似边数跟题目描述不太一样。
代码:

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
const int N=1e5+5,M=2e6+5,mod=6;
int T,n,m,K,first[N],cnt=0,tot=0,fa[N],col[N],ans;
struct edge{int v,next;}e[M<<1];
inline void addedge(int u,int v){e[++cnt].v=v,e[cnt].next=first[u],first[u]=cnt;}
inline void add(int u,int v){addedge(u,v),addedge(v,u);}
inline bool dfs(int p,int f){
	col[p]=f;
	for(int i=first[p];i;i=e[i].next){
		int v=e[i].v;
		if(~col[v]){if(!(col[v]^f))return false;}
		else if(!dfs(v,f^1))return false;
	}
	return true;
}
inline int find(int x){return x==fa[x]?fa[x]:fa[x]=find(fa[x]);}
int main(){
	T=read();
	while(T--){
		n=read(),m=read(),K=read();
		if(!m){
			ans=1;
			for(int i=1;i<n;++i){
				ans<<=1;
				if(ans>=mod)ans-=mod;
			}
			--ans;
			if(ans<0)ans+=mod;
			ans=ans*K%mod*(K-1)%mod;
			ans+=K%mod;
			if(ans>=mod)ans-=mod;
		}
		else{
			cnt=0,tot=0,ans=1;
			for(int i=1;i<=n;++i)first[i]=0,fa[i]=i,col[i]=-1;
			for(int i=1,u,v,fx,fy;i<=m;++i){
				u=read(),v=read(),add(u,v),add(v,u),fx=find(u),fy=find(v);
				if(fx!=fy)fa[fx]=fy;
			}
			for(int i=1,f;i<=n;++i)
				if(~col[i])continue;
				else{
					if(!dfs(i,0)){ans=0;break;}
					++tot;
				}
			if(ans){
				for(int i=1;i<tot;++i){
					ans<<=1;
					if(ans>=mod)ans-=mod;
				}
				ans=ans*K%mod*(K-1)%mod;
			}
		}
		printf("%d\n",ans); 
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值