题目分析:
考虑到这是一个区间的异或问题,不妨求出前缀和,令$sum[i] = Xor_{j=1}^{i}a[j]$。
对于区间$[l,r]$的异或结果,等于$sum[r] \oplus sum[l-1]$。那么原问题等价于选尽量多的点$p_x$,使得这些点构成的$sum[p_x] \oplus sum[p_{x-1}]$的子集的异或非$0$。我们不断往前异或,可以把问题转化为选尽量多的$p_x$,使得$sum[p_x]$的子集的异或非$0$。这是因为这两者的线性基等价。
这样子这题就变成BZOJ2460的弱化版了。关于BZOJ2460的证明,我还没想到。想到了我会补链接。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 205000; 5 6 int n,a[maxn]; 7 8 int p[50]; 9 10 void read(){ 11 scanf("%d",&n); 12 for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i] ^= a[i-1]; 13 } 14 15 void work(){ 16 if(a[n] == 0){puts("-1");return;} 17 for(int i=30;i>=0;i--)if(a[n] & (1<<i)) {p[i] = a[n];break;} 18 int ans = 1; 19 for(int i=1;i<n;i++){ 20 for(int j=30;j>=0;j--){ 21 if(a[i] & (1<<j)){ 22 if(p[j]) a[i] ^= p[j]; 23 else{p[j] = a[i];ans++;break;} 24 } 25 } 26 } 27 printf("%d\n",ans); 28 } 29 30 int main(){ 31 read(); 32 work(); 33 return 0; 34 }