CF1604B XOR Specia-LIS-t 题解

考场上想出了近似做法,可惜没有实现出来。

题意

\(t\) 组数据,每组都是一个有 \(n\) 个元素的序列 \(a\),考虑将此序列分割成若干段。假设第 \(i\) 段的 LIS(最长上升子序列)长度为 \(h_i\),请问是否有一种分割方式使得 \(h_1 \oplus h_2\oplus\dots\) 的值为 \(0\)

数据范围 \(1\leqslant t\leqslant10000\)\(2\leqslant n\leqslant10^5\),所有 \(n\) 之和不超过 \(3\cdot 10^5\)

思路

肯定不能每次暴力分割,所以考虑 LIS 的性质。

  • 一个单调不升序列的 LIS 一定是 \(1\)
  • 一个元素的序列的 LIS 一定是 \(1\)

再很容易想到,一堆 \(1\) 异或起来,答案不是 \(1\) 就是 \(0\)。偶数个 \(1\) 异或,答案就是 \(0\);奇数个 \(1\) 异或,答案是 \(1\),再来一个 \(1\) 答案就能变成 \(0\)

所以对于 \(n\bmod 2=0\) 的情况一定有解(每个元素单独成一段),而对于 \(n\bmod 2=1\) 的情况,考虑把两个元素合为一段,剩下的元素还是单独成段。若合起来的两个元素刚好构成一个单调不升序列就有解,否则无解。

代码

数学题的好处就是想清楚了代码很精简。

//solve 函数的主体
cin>>n;
for(int i=1;i<=n;i++){
	cin>>a[i];
}
if(n%2==0){//偶数元素一定有解
	puts("YES");
	return;
}
else{
	for(int i=2;i<=n;i++){
		if(a[i-1]>=a[i]){//判断是否可以组成单调不升序列
			puts("YES");//有两个元素能组成就有解
			return;
		}
	}
	puts("NO");//如果组成不了单调不升序列就没有解
	return;
}

AC 记录

AC 链接

posted @ 2022-01-26 16:47  Shunpower  阅读(33)  评论(0编辑  收藏  举报