codeforces 1149E Election Promises Nim游戏

博客围绕一道与Nim游戏相关的题目展开分析。若没有‘任意修改相邻城市的税收’操作就是Nim游戏,解题思路是将城市分组,依据组的异或和判断胜负。若每组异或和为0则一方必败,否则必胜,还给出了第一步的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目分析

这题好喵啊。
喵啊

如果没有“任意修改相邻城市的税收”这个操作,就是个美滋滋的Nim游戏。

接下来的思路就很巧妙了,将城市分组。所有出度为0的点为第0组,其他点为第mex(其可达节点的组编号)组。

这个有两个性质:

  1. 同一组不存在一对节点xxx,yyy,满足存在边(x,y)(x,y)(x,y)
  2. 对于第ttt组中的任意一个点,它可以到达第000到第ttt组,每一组中的至少一点。

若每一组的异或和都为0,则WA党必败,否则必胜。

第一步的策略就是,找到编号最大的,异或和不为0的组,找到其中一个可以通过减少税收使得改组异或和变为0的点,通过在这个点上拉票,修改其相邻城市的税收,使得每一组的异或和都变为0。

代码

#include<bits/stdc++.h>
using namespace std;
#define RI register int
int read() {
	int q=0;char ch=' ';
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9') q=q*10+ch-'0',ch=getchar();
	return q;
}
const int N=200005;
int n,m,tot,cnt;
int h[N],ne[N],to[N],w[N],du[N],stk[N],seq[N],id[N],vis[N],sg[N];

void add(int x,int y) {to[++tot]=y,ne[tot]=h[x],h[x]=tot;}
void toposort() {
	int top=0,js=0;
	for(RI i=1;i<=n;++i) if(!du[i]) stk[++top]=i;
	while(top) {
		int x=stk[top];--top,seq[++js]=x;
		for(RI i=h[x];i;i=ne[i]) {
			--du[to[i]];
			if(!du[to[i]]) stk[++top]=to[i];
		}
	}
	for(RI i=n;i>=1;--i) {
		int x=seq[i];
		for(RI j=h[x];j;j=ne[j]) ++vis[id[to[j]]];
		while(vis[id[x]]) ++id[x];
		if(id[x]>cnt) cnt=id[x];
		for(RI j=h[x];j;j=ne[j]) --vis[id[to[j]]];
	}
}

int main()
{
	int x,y;
	n=read(),m=read();
	for(RI i=1;i<=n;++i) w[i]=read();
	for(RI i=1;i<=m;++i) x=read(),y=read(),add(x,y),++du[y];
	toposort();
	for(RI i=1;i<=n;++i) sg[id[i]]^=w[i];
	int flag=-1;
	for(RI i=0;i<=cnt;++i) if(sg[i]) flag=i;
	if(flag==-1) {puts("LOSE");return 0;}
	puts("WIN");
	for(RI i=1;i<=n;++i) if(id[i]==flag) {
		if((sg[id[i]]^w[i])>w[i]) continue;
		w[i]^=sg[id[i]],sg[id[i]]=0;
		for(RI j=h[i];j;j=ne[j])
			w[to[j]]^=sg[id[to[j]]],sg[id[to[j]]]=0;
	}
	for(RI i=1;i<=n;++i) printf("%d ",w[i]);
	puts("");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值