CF1149E Election Promises
Link
首先求出每个点的SG函数值,即SG(u)=mex{SG(v)|v∈sonu}。
然后求出sumx=xorSG(u=xau。
那么先手必胜当且仅当存在sumx非零。
如果sum全为0,那么先手操作u之后sumSG(u)一定会变化。
如果存在sumx非零,那么我们找到x=max,然后再任选一个u\in\{u|SG(u)=x\wedge a_u>a_u\operatorname{xor} sum_x\}。
然后我们将a_u修改为a_u\operatorname{xor}sum_x,这样sum_x就变成了0。
然后\forall i\in[0,x),若sum_i>0,就找到v\in\{v|v\in son_u\wedge SG(v)=i\},然后修改a_v为a_v\operatorname{xor}sum_i即可。
显然这都是能够找到的,那么我们就将必胜态转化为了必败态。
#include<queue>
#include<cctype>
#include<cstdio>
#include<vector>
const int N=200007;
int a[N],deg[N],pos[N],vis[N],sg[N],sum[N];std::queue<int>q;std::vector<int>e[N];
int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
int main()
{
int n=read(),m=read();
for(int i=1;i<=n;++i) a[i]=read();
for(int i=1,u,v;i<=m;++i) u=read(),v=read(),e[u].push_back(v),++deg[v];
for(int i=1;i<=n;++i) if(!deg[i]) q.push(i);
for(int u,c=0;!q.empty();)
{
u=q.front(),q.pop(),pos[++c]=u;
for(int v:e[u]) if(!--deg[v]) q.push(v);
}
for(int i=n,u;i;--i)
{
u=pos[i];
for(int v:e[u]) vis[sg[v]]=i;
while(vis[sg[u]]==i) ++sg[u];
sum[sg[u]]^=a[u];
}
for(int i=n,u;~i;--i)
if(sum[i])
{
for(int j=1;j<=n;++j) if(sg[j]==i&&a[j]>(sum[i]^a[j])) u=j;
a[u]^=sum[i];
for(int v:e[u]) a[v]^=sum[sg[v]],sum[sg[v]]=0;
puts("WIN");
for(int j=1;j<=n;++j) printf("%d ",a[j]);
return 0;
}
puts("LOSE");
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步