CF1604B XOR Specia-LIS-t
题目大意
给出一个长度为 \(n\) 的整数序列 \(a\),将其划分为 \(k\) 个连续子串。
设 \(h_1, h_2, h_3...h_k\) 是每个子串的最长上升字序列的长度。
求是否有一种划分方式使得 \(h_1 \oplus h_2 \oplus h_3 \oplus ... \oplus h_n = 0\)。
有则输出 YES;否则输出 NO。
题目分析
妙题。
\(h_1 \oplus h_2 \oplus h_3 \oplus ... \oplus h_n = 0\),可以转化成 \(h_1=h_2=\cdots=h_{n-1}=h_n\)(也可以转化成其他形式,但这样非常方便)。
当 \(n\) 为偶数时,可将每个数单独拎出来,显然符合题目要求,直接输出 YES。(此时 \(h_1=h_2=\cdots=h_{n-1}=h_n=1\),\(h_1\oplus h_2\oplus \cdots \oplus h_n=0\))
当 \(n\) 为奇数时,如果发现 \(a_{i-1}\ge a_i\),那么如果这两个放一组,这一组必然不会出现长度不等于 \(1\) 的最长上升子序列,再把其它数各自分成一组,就转换成了偶数的情况,直接输出 YES。
否则说明该序列为严格递增序列,不可能满足要求,输出 NO。
代码
//2021/11/18
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <climits>//need "INT_MAX","INT_MIN"
#include <cstring>
#define enter() putchar(10)
#define debug(c,que) cerr<<#c<<" = "<<c<<que
#define cek(c) puts(c)
#define blow(arr,st,ed,w) for(register int i=(st);i<=(ed);i++)cout<<arr[i]<<w;
#define speed_up() std::ios::sync_with_stdio(false)
#define endl "\n"
namespace Newstd
{
inline int read()
{
char c;
bool flag=false;
while((c=getchar())<'0' || c>'9')
{
if(c=='-') flag=true;
}
int res=c-'0';
while((c=getchar())>='0' && c<='9')
{
res=(res<<3)+(res<<1)+c-'0';
}
return flag?-res:res;
}
inline void print(int x)
{
if(x<0)
{
putchar('-');x=-x;
}
if(x>9)
{
print(x/10);
}
putchar(x%10+'0');
}
}
using namespace Newstd;
using namespace std;
const int ma=100005;
int a[ma];
int T,n;
inline void init()
{
memset(a,0,sizeof(a));
}
int main(void)
{
T=read();
while(T--)
{
init();
n=read();
for(register int i=1;i<=n;i++)
{
a[i]=read();
}
if(n%2==0)
{
puts("YES");
continue;
}
bool mark=false;
for(register int i=1;i<n;i++)
{
if(a[i]>=a[i+1])
{
mark=true;
break;
}
}
if(mark==true)
{
puts("YES");
}
else
{
puts("NO");
}
}
return 0;
}

浙公网安备 33010602011771号