Problem F. Grab The Tree
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 363 Accepted Submission(s): 247
Problem Description
Little Q and Little T are playing a game on a tree. There are n vertices on the tree, labeled by 1,2,...,n, connected by n−1 bidirectional edges. The i-th vertex has the value of wi.
In this game, Little Q needs to grab some vertices on the tree. He can select any number of vertices to grab, but he is not allowed to grab both vertices that are adjacent on the tree. That is, if there is an edge between x and y, he can't grab both x and y. After Q's move, Little T will grab all of the rest vertices. So when the game finishes, every vertex will be occupied by either Q or T.
The final score of each player is the bitwise XOR sum of his choosen vertices' value. The one who has the higher score will win the game. It is also possible for the game to end in a draw. Assume they all will play optimally, please write a program to predict the result.
Input
The first line of the input contains an integer T(1≤T≤20), denoting the number of test cases.
In each test case, there is one integer n(1≤n≤100000) in the first line, denoting the number of vertices.
In the next line, there are n integers w1,w2,...,wn(1≤wi≤109), denoting the value of each vertex.
For the next n−1 lines, each line contains two integers u and v, denoting a bidirectional edge between vertex u and v.
Output
For each test case, print a single line containing a word, denoting the result. If Q wins, please print Q. If T wins, please print T. And if the game ends in a draw, please print D.
Sample Input
1
3
2 2 2
1 2
1 3
Sample Output
Q
题意:
有 n 个点,每个点有权值,输入 n-1 条边
小 Q 先手选点,如果两点之间相连,就只能选其中一个点。然后剩下的所有点都是小 T 的。
求他们所选点的亦或和(XOR),谁的大,谁胜利。
XOR(亦或和):第一组样例,假设小Q 选了第一个点 sumQ = 2, sumT = 2^2 = 0。亦或和就是选择的点进行亦或运算得到的数。
题解:
看到这个题一开始就在疯狂的想连通图,非连通图各种跟图相关的算法,然后又没结果,仔细看了下题才发现
这道题连不连线一点关系都没有。只要解决了亦或和,这道题就很简单了。
我们知道两人选完后,树上所有的点都被分成了两堆,他们各自的亦或和设为sumQ,sumT。所有点的亦或和设为sum。
所以sumQ ^ sumT = sum。那么sum分为两种情况:sum==0 或者 sum!=0
- sum == 0:如果sum == 0,说明两人的亦或和相等,平局
- sum != 0:如果sum != 0,那么小 Q 只需要选一个最高位跟sum 二进制下最高位一样的数,那么小 Q 必赢。这种数必定只有奇数个,因为偶数个的话,sum 的这一位一定是0;
例如:
1:0001
2:0010
4:0100
9:1001
10:1010
sum = 1^2^4^9^10 = 4(0100) 最高位为“3”(从右往左数),可以发现上面例子中,只有4符合,那么小Q 选4,剩下的给小T ,亦或和后,小T 的一定比小Q 小。
所以这个游戏只有两个情况:平局或者小Q胜。
代码:
#include <stdio.h>
int main(){
int t;
while (scanf("%d",&t) != EOF){
while (t--){
int n;
long long sum = 0, a;
scanf("%d",&n);
for (int i = 0; i < n; i++){
scanf("%lld",&a);
sum ^= a;
}
//下面的连线没啥用
int u,v;
for (int i = 0; i < n-1; i++){
scanf("%d %d",&u,&v);
}
if (sum == 0) printf("D\n");
else printf("Q\n");
}
}
}