CF1604B 题解

CF1604B 题解

题面

原题传送门

题意

给定一个长度为 n 的数组 a,将 a 分成若干段,问是否有一种分段的方法使得每一段的最大上升子序列的长度的异或和为 0

有多组数据。

前置知识

  1. 位运算,知道异或算法相同为假,不同为真,理解并能够运用 11=0
  2. 数学归纳法(证明思路的时候会用到)。

思路(做法)

  1. n 为偶数时,显然只需将 a 分成 n 段,每一段一个数字即可。这样每一段的最大上升子序列的长度为 1,且有偶数个段,因为 11=0,所以最终得到的结果也必为 0
  2. n 为奇数时,如果还是像上面这种简单粗暴的方法来构造的话,结果必定为 1(因为 n 为奇数)。所以就想到,要是有一个 i(i[1,n1]),使得 aiai+1,的话,则把 ai,ai+1 放在一组,其余的一个数一组,这样的话,ai,ai+1 这一组的最大上升子序列的长度为 1,总共有偶数个 1 异或,则结果为 1。若不存在这样的 i,则无解。

思路正确性的证明

其实,上面的输出 YES 的方法不多说,不懂的话再看看题目,现在要证明为什么不存在 i(i[1,n1]) 使得 aiai+1 的话就无解。

首先,我们知道,要是不存在这样的 i,则 a 为一个上升序列,所以不管怎么分段,分的那一段最大上升子序列的长度必定就为那一段的长度,那么就有以下证明:

引理:若有正整数 a,b,则 ab 的结果的奇偶性与 a+b 的结果的奇偶性相同。

引理证明:

a,b 在二进制表达下的最后一位分别为 a,b(a,b{0,1}),则有以下两种情况:

  1. a=b,则由异或的运算规则,ab 的结果为偶数,又由加法的运算规则,a+b 的结果也为偶数。所以两者奇偶性相同。
  2. ab,则由异或的运算规则,ab 的结果为奇数,又由加法的运算规则,a+b 的结果也为奇数。所以两者奇偶性相同。

综上,ab 的结果的奇偶性与 a+b 的结果的奇偶性相同。

证毕。

回到证明思路的正确性,咱们设每一段的最大上升子序列的长度为 b 数组,一共分成了 m 段。则 b1+b2+b3++bm=n 且为奇数。

由引理,b1b2 奇偶性与 b1+b2 相同。

同理,(b1b2)b3 奇偶性与 (b1+b2)+b3 相同。(把 b1+b2 看成一个整体。)

由数学归纳法得,b1b2b3bn 奇偶性与 b1+b2+b3++bm 相同。

所以,b1b2b3bn 为奇数。

0 为偶数,所以这种情况必定输出 NO

证毕。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
long long T,n,a[100005];
bool flag;
int main(){
	scanf("%lld",&T);//多组数据 
	while(T--){
		flag=false;//初始化 
		scanf("%lld",&n);
		if(n%2==0) flag=true;//直接可以 
		for(int i=0; i<n; i++){
			scanf("%lld",&a[i]);
			if(i&&a[i]<=a[i-1]) flag=true;//这也是可以的 
		}
		if(flag) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
} 
posted @   naroto2022  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
花开如火,也如寂寞。