题意
给出一个长度为 (n) 非递减的序列 (a),可以执行操作一次或者多次:选择两个相邻的数字将他们删去,并在此位置添加他们的异或和。问最少需要多少次操作使序列不是非递减的?
$2≤n≤105,1≤a_i≤109 $
分析
首先,可以发现,当连续 (3) 个数的最高位相同时,必然可以通过将其中两个数异或来达到目的。结合序列非递减的条件,可以得出当 (n>60) 时,答案必然为 (1)。
对于 (nleq 60) 的情况,我们直接枚举需要异或合并的区间一定是连续的。那么,就可以枚举区间的左右端点,然后再枚举区间的断点,比较断点两边的数是否满足要求,求出最小值即可。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N];
int sum[N];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
if(n>60)//必然有连续3个数的最高位相同
printf("1
");
else
{
int ans=n+1;
sum[0]=0;
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]^a[i];
for(int i=1;i<=n;i++)
{
for(int j=i+2;j<=n;j++)
{
for(int k=i;k<j;k++)
{
int x=sum[k]^sum[i-1];
int y=sum[j]^sum[k];
if(x>y)
ans=min(ans,j-i-1);
}
}
}
printf("%d
",ans==n+1?-1:ans);
}
return 0;
}
/*
4
11 22 71 92
*/