【题意】
初始给定长度为 (n),非递减的序列 ({a_n}) 。你可以进行操作,每次操作将两个相邻的数字消除,换为它们的异或和。问最少需要多少步使得原序列不再非递减。
【分析】
由于 (a_ileq 10^9) 且 (2^{29}<10^9<2^{30})
故根据抽屉原理,当数量 (ngeq 2 imes 30+1=61) 时,至少存在一个位数,使得以该位数为最高位的数字存在至少 (3) 个,且这 (3) 个数连续。
设上述的其中一组 (3) 个数在序列中位置分别为 (a_{pos}, a_{pos+1}, a_{pos+2}) 。
则 (a_{pos+1}otimes a_{pos+2}) 的原最高位被异或消除,必定小于 (a_{pos}) ,则直接打破了非递减性。
因此,当 (ngeq 61) 时,答案为 (1) 。
当 (nleq 60) 时,采用随机化的方式,取步数最少解。
当不存在该解时,直接输出 (-1) 。
【代码】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef double db;
#define fi first
#define se second
const int MAXN=1e5+10;
int n, a[MAXN], b[MAXN];
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
clock_t start = clock();
cin>>n;
for(int i=1;i<=n;++i) cin>>a[i];
if(n>60)
cout<<1;
else{
int ans=0;
do{
memcpy(b+1, a+1, sizeof(a[0])*n);
int len=n;
while(len>1){
for(int i=1;i<len;++i)
if(b[i]>b[i+1]){
ans=max(ans, len);
break;
}
--len;
int pos=rand()%len+1;
b[pos]^=b[pos+1];
for(int i=pos+1;i<=len;++i)
b[i]=b[i+1];
}
}while( clock()-start<=1980 );
if(ans) cout<<n-ans;
else cout<<-1;
}
cout.flush();
return 0;
}