标签:条件 lan signed man sign 开始 长度 相同 变异
给定一棵\(n\)个节点的苹果树,第\(i\)个点上有\(a_i\)个苹果。这棵树有一个特殊的性质是:从根到任何叶子的路径长度的奇偶性相同。
Sagheer 和 Soliman 将在树上轮流移动,Soliman 先手,当轮到某个玩家在自己的回合不能移动时这个玩家失败。
每次移动时,两个玩家都可以任意选择一个节点,从中取出至少一个苹果,进行以下两种操作之一:
在每次游戏开始之前,Sagheer 可以对苹果树进行一次更改:选择两个节点\(u,v(u\ne v)\)然后交换\(a_u,a_v\)。
假设双方都走最优方案,求出有多少对\((u,v)\)满足后手获胜(\((u,v)\)与\((v,u)\)视为一样)。
在标准nim游戏中,直接计算每堆石子的异或值,若异或值为\(0\),则先手必败,否则先手必胜。
而nim游戏的某个变体为有一个额外操作,允许玩家将\(>0\)个石子加入某个石堆中(以及给定一些使游戏不会无限进行的条件),那么这个问题的解决方案类似于标准nim游戏,因为这个额外的操作将被原本获胜的玩家使用,而当原本失败的玩家使用时,原本胜利的玩家可以通过扔掉这些被加入的石子。
而本题可以建模为上面所提到的变体。令所有叶节点为黑色,然后让所有黑色节点的父亲为白色,白色节点的父亲为黑色……这样黑白染色之后,黑色节点就可以看成石堆,而白色节点就可以看成拿石子或加石子的操作。
注意到由于题目保证了题目保证了从根到任何叶子的路径长度的奇偶性相同,因此不会有一个节点有两种颜色。
所以说,若所有黑色节点的异或值\(s=0\),则在初始树上 Soliman 为先手必败,而为了保持这种状态,Sagheer 可以进行以下两个操作:
若所有黑色节点的异或值\(s\neq 0\),则在初始树上 Sagheer 为后手必败。因此为了交换后改变异或值满足\(s=0\),Sagheer 需要将某个黑色节点\(u\)与白色节点\(v\)交换满足\(s\oplus a_u \oplus a_v=0\)。
时间复杂度为线性。
int n;
int col[111111];
vector<int>e[111111],blk;
int a[111111],cnt[2];
map<int,int>mp;
int s,ans;
void dfs(int u)
{
for(int v:e[u]) dfs(v);
if(e[u].size()==0) col[u]=0;
else col[u]=col[e[u][0]]^1;
if(!col[u]) s^=a[u],blk.pb(a[u]);
else ++mp[a[u]];
++cnt[col[u]];
}
signed main()
{
n=read();
R(i,1,n) a[i]=read();
R(i,2,n) e[read()].pb(i);
dfs(1);
if(s==0)
{
ans=(cnt[0]*(cnt[0]-1ll)+cnt[1]*(cnt[1]-1))>>1;
for(int x:blk) ans+=mp[x];
}
else
{
for(int x:blk) if((x^s)<=10000000) ans+=mp[x^s];
}
writeln(ans);
}
标签:条件 lan signed man sign 开始 长度 相同 变异
原文地址:https://www.cnblogs.com/hizeci/p/14902947.html