题目链接:https://codeforces.ml/contest/1457/problem/D
题意:给定一个长度为n(2<=n<=1e5)的不减数组a(a[i]<=a[i+1])。1<=ai<=1e9。每次可以执行操作:选择两个相邻的数组去掉这个数,然后在原来位置加上这两个数的异或结果。
问最少经过多少次能够使这个数组不满足不减数组。
题解:分析
1.二进制,如果任意三个连续的数最高位数相同,那么一定可以取依次异或(后面两个数)使这个数组不满足条件。ans=1;
这种情况只需要暴力一遍就可以排序,除了这种情况最坏的情况就是::数组位数:1 1 2 2 .... k k(k为可能的最高位数,一定不超过30,因为1e9<2^30)。
2.另外,加入答案为cnt。那么最后处理两段连续的数组(否则就不想关联了,这里需要理解一下)。
3.然后考虑暴力cnt。见代码注释吧。
#include <bits/stdc++.h>
#define ll long long
#define ld double
#define pi acos(-1)
#define pb push_back
#define mst(a, i) memset(a, i, sizeof(a))
#define pll pair<ll, ll>
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define rep(i, a, n) for (ll i = a; i <= n; i++)
#define per(i, n, a) for (ll i = n; i >= a; i--)
#define dbg(x) cout << #x << "===" << x << endl
#define dbgg(l, r, x) \
for (ll i = l; i <= r; i++) \
cout << x[i] << " "; \
cout << "<<<" << #x; \
cout << endl
using namespace std;
template <class T> void read(T &x) {
T res = 0, f = 1;
char c = getchar();
while (!isdigit(c)) {
if (c == '-') f = -1;
c = getchar();
}
while (isdigit(c)) {
res = (res << 3) + (res << 1) + c - '0';
c = getchar();
}
x = res * f;
}
inline void print(ll x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) print(x / 10);
putchar(x % 10 + '0');
}
const ll maxn = 1e5 + 10;
const ll mod = 1e9 + 7;
ll n, a[maxn];
ll sum[maxn];
int main() {
ll _s = 1;
// read(_s);
for (ll _ = 1; _ <= _s; _++) {
read(n);
mst(a, 0);
rep(i, 1, n) read(a[i]), sum[i] = sum[i - 1] ^ a[i];
ll b, c, cnt = 0;
ll l, r;
while (1) {
++cnt;//暴力讨论cnt
rep(i, 1, n) {
rep(j, 1, cnt) {
//第一段(i,i+j)操作j次
if (i + j <= n) {
b = sum[i + j] ^ sum[i - 1];
//与前面一个数相比
if (i - 1 >= 1 && b < a[i - 1]) {
cout << cnt << endl;
return 0;
}
//与后面一个数比
if (i + j + 1 <= n && b > a[i + j + 1]) {
cout << cnt << endl;
return 0;
}
}
//第二段(i+j+1,i+j+1+(cnt-j))操作(cnt-j)次
r = i + j + 1 + (cnt - j);
if (r <= n) {
c = sum[r] ^ sum[i + j];
if (c < a[i + j]) {
cout << cnt << endl;
return 0;
}
if (r + 1 <= n && c > a[r + 1]) {
cout << cnt << endl;
return 0;
}
}
//前一段与后一段比
if (r <= n && b > c) {
cout << cnt << endl;
return 0;
}
}
// if(cnt>=n||cnt>=100) break;
}
if (cnt >= n || cnt >= 60) break;
}
cout << -1 << endl;
}
return 0;
}
/*
input:::
output:::
*/