[CSP-S模拟测试]:最大异或和(数学)

题目传送门(内部题81)


输入格式

  第一行一个整数$T(T\leqslant 20)$,表示测试数据组数
  接下来$T$组,对于每一组,第一行一个整数$n$
  第二行有$n$个整数,为$w_1,w_2...w_n$
  接下来$n-1$行,每行两个整数$x,y$,表示$x$和$y$之间有一条边连接


输出格式

  对于每一组,答案只有一行,如果小$Q$获胜输出$Q$,小$T$获胜输出$T$,如果平局输出$D$。


样例

样例输入:

2
3
2 2 2
1 2
1 3
4
7 1 4 2
1 2
1 3
2 4

样例输出:

Q
D


数据范围与提示

样例解释:

在第一组中,小$Q$选择任意一个节点,分数为$2$,小$T$选择剩下两个节点,分数为$0$,小$Q$获胜
在第二组中,小$Q$最好只能和小$T$平局,所以输出$D$

数据范围:

对于$30\%$的数据,$n\leqslant 20$
对于$100\%$的数据,$n\leqslant 100,000,w_i\leqslant 10^9$。


题解

小$Q$肯定不可能输,平局的情况当且仅当所有的$w_i$异或和为$0$时才能发生,否则小$Q$一定不能获胜。

因为出题人出此题意在送分,于是可能有各种不同的错解可以通过此题(听说对拍只能抗住$6,7$个点的假$DP$还能拿到$90$分)……

时间复杂度:$\Theta(T\times n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int n;
int w;
int XOR;
int main()
{
	int T;scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);XOR=0;
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&w);
			XOR^=w;
		}
		for(int i=1;i<n;i++)
			scanf("%d%d",&w,&w);
		if(XOR)puts("Q");
		else puts("D");
	}
	return 0;
}

rp++

posted @ 2019-10-24 07:11  HEOI-动动  阅读(135)  评论(0编辑  收藏  举报