Problem F. Grab The Tree
题意:有一棵树,每个节点都有一个值,Q首先选择任意个点,但是所选点不能有连边,也就是选了儿子就不能选父亲,选了父亲就不能选儿子;Q选完后T选;比较最后每个人选的数的异或和,谁大谁赢,相等就是平局;
竟然写了半天树形DP,然后就莫名其妙的AC了~~~;
先说一下为什么不能用树形DP,这不是模板吗???要么选父亲,要么选儿子,选最大的,不就是树形DP了???
还真不是,为啥子嘞?
异或运算并不是谁大就异或谁就变大了,不对!!!!!!!!!!
100^100=0, 3^4=7....................
就是因为异或运算这个特殊性质,导致了我们的状态转移不合理!!!!
那么这个题到底咋做嘞??????
看到博客标题了吧!!!博弈!!!!!!!!!!!!
先初始化所有节点的异或和,记为sum;
若sum>0,则最高位第k位为1的数一定是奇数个,Q只要拿走一个第k位为1的,剩下的数的异或和在第k位一定是0;Q必胜;
sum=0时,一定有一种状态使得两人拿到的数的异或和相同,此时就是平局了;
#include <bits/stdc++.h>
using namespace std;
int main(){
int T;
scanf("%d", &T);
while(T--){
int n;
scanf("%d", &n);
int sum=0, x, y;
for(int i=0; i<n; i++){
scanf("%d", &x);
sum^=x;
}
for(int i=1; i<n; i++)
scanf("%d%d", &x, &y);
if(sum==0) printf("D\n");
else printf("Q\n");
}
return 0;
}