题意:
给出一个长度为n的非递减数组,每次可以选择连续的两个数,将这两个数删除,并将他们的异或值加入到删除的位置,问至少要几次操作才可以让数组不再是非递减。
题解:
1.假如数组中存在连续的三个数,它们的最高位的1都在同一个位置,那么直接让后面两个数异或,这样得到的值必小于第一个。
2.若不存在,说明数组中只可能存在两个连续的数的最高位的1在同一个位置,甚至都不相同,因为元素<=1e9,所以它们的位数不会超过30位,也就是说,假如每一位都有两个连续的数的最高位的1在这一位,数组也只有2*30个元素,然后就可以直接暴力找两个连续区间,判断两个区间异或值大小,求出答案。
结论:当n>=100时,直接输出1,否则暴力找答案。
代码:
#include<bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int MAXN=1e5+5;
const int mod=1e9+7;
int a[MAXN];
int sum[MAXN];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum[i]=sum[i-1]^a[i];
}
int ans=1e9;
if(n>=100)
{
ans=1;
}
else
{
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
for(int k=i;k<j;k++)
{
int k1=sum[k]^sum[i-1];
int k2=sum[j]^sum[k];
if(k1>k2) ans=min(ans,j-i-1);
}
}
}
}
if(ans==1e9) cout<<-1<<endl;
else cout<<ans<<endl;
}