https://codeforces.com/contest/1457/problem/D
话说这场D吃完饭hack了400+人。
思路:开始看到以为答案只有-1,1,2三种,但是并不是。
构造发现如果连续三位的最高位1位置一样,那么就能1次达到目的。
那么这种情况下的极限是什么呢?
0001
0010
0011
01??
01??
1???
1???
可以看到,在最大值1e9的情况下,当序列里刚好不冲突的时候,有60个数字。剩下进去就必然可以1次。
那么题目就剪枝到60以下了。
考虑两个情况:一个是一个区间直接异或出来波峰或者波谷。(n^2)
另一个是两个连续区间分别异或再合并出来的情况。(n^3)
代码上设置边界a[n+1]=1e18;
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=100;
typedef long long LL;
LL a[maxn];
LL sum[maxn];
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
LL n;cin>>n;
if(n>60){
cout<<"1"<<endl;
return 0;
}
a[n+1]=1e18;
for(LL i=1;i<=n;i++) cin>>a[i];
for(LL i=1;i<=n;i++){
sum[i]=sum[i-1]^a[i];
}
LL res=1e18;
for(LL l=1;l<=n;l++){
for(LL r=l+1;r<=n;r++){
LL t=sum[r]^sum[l-1];
if(t>a[r+1]||t<a[l-1]){
res=min(res,r-l+1-1);
/// debug(res);
}
}
}
for(LL i=1;i<=n;i++){///[i,j][j+1,k]
for(LL j=i+1;j<=n;j++){
for(LL k=j+1;k<=n;k++){
LL t1=sum[j]^sum[i-1];
LL t2=sum[k]^sum[j];
if(t1>t2){
res=min(res,k-j+1-1+j-i+1-1-1);
}
}
}
}
if(res==1e18){
cout<<"-1"<<endl;
}
else cout<<res<<endl;
return 0;
}