题目链接:Grab The Tree
题意
小 Q Q 和小 玩一个游戏,在一棵 n n 个节点的树上,每个节点都有一个权值 ,由小 Q Q 先开始选点,小 选择的点中,任意两个节点不能同时为某条边的两个端点,之后剩下的点全是小 T T 的,小 的最终分数就是他所选择的所有点的权值异或值,小 T T 的分数也是他拥有的点的权值异或值,问在小 采取最优策略的情况下,谁会获胜,还是平局。
输入
第一行包含一个整数 T (1≤T≤20) T ( 1 ≤ T ≤ 20 ) ,接下去有 T T 组数据,每组数据第一行为一个整数 ,第二行为 n n 个整数 ,接下去 n−1 n − 1 行每行两个整数 u,v (1≤u,v≤n) u , v ( 1 ≤ u , v ≤ n ) ,表示节点 u,v u , v 之间有一条边。
输出
如果小 Q Q 会获胜,则输出 ,如果小 T T 会获胜,则输出 ,否则输出 D D 。
样例
输入 |
---|
1 3 2 2 2 1 2 1 3 |
输出 |
Q |
题解
如果树上所有点的异或值为 ,无论小 Q Q 如何选点,小 的分数都会和小 Q Q 的分数相等,如果树上所有点的异或值非 ,则小 Q Q 只需要选择最大值,就可以让树上所有其他点异或值的最高位小于小 选择的点的权值,小 Q Q <script type="math/tex" id="MathJax-Element-31">Q</script> 必胜。
过题代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <unordered_set>
#include <unordered_map>
using namespace std;
#define LL long long
int T, n, num, Xor, u, v;
int main() {
#ifdef LOCAL
freopen("test.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // LOCAL
ios::sync_with_stdio(true);
scanf("%d", &T);
while(T--) {
Xor = 0;
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
scanf("%d", &num);
Xor ^= num;
}
for(int i = 1; i < n; ++i) {
scanf("%d%d", &u, &v);
}
if(Xor == 0) {
printf("D\n");
} else {
printf("Q\n");
}
}
return 0;
}