题意:给出一个序列,试将其划分为尽可能多的非空子段,满足每一个元素出现且仅出现在其中一个子段中,且在这些子段中任取若干子段,它们包含的所有数的异或和不能为0.
思路:先处理出前缀异或,这样选择更多的区间其实就相当于选择更多的前缀异或,并且这些前缀异或不能异或出0,这就变成了线性基的基础题了。贪心的放,能放就放。不能放就意味着线性基的add函数里面的val最后变成了0,也就是当前已经插入的线性基已经可以异或出正在插入的数了,所以不能放。
(今天真巧,一连遇到两道线性基的题目)
#include<bits/stdc++.h> #define clr(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; const int maxn=2e5+10; ll a[maxn],p[40],s[maxn]; int n; int add(ll val){ for(int i=30;i>=0;i--) { if(val&(1<<i)){ if(!p[i]){ p[i]=val; return 1; } val^=p[i]; } } return 0; } int main(){ while(cin>>n) { clr(p,0); for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); s[i]=s[i-1]^a[i]; } if(s[n]==0){ puts("-1"); continue; } int ans=0; for(int i=n;i>0;i--) { ans+=add(a[i]); } cout<<ans<<endl; } }
You are given an array a1,a2,…,ana1,a2,…,an of integer numbers.
Your task is to divide the array into the maximum number of segments in such a way that:
- each element is contained in exactly one segment;
- each segment contains at least one element;
- there doesn't exist a non-empty subset of segments such that bitwise XOR of the numbers from them is equal to 00.
Print the maximum number of segments the array can be divided into. Print -1 if no suitable division exists.
The first line contains a single integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the size of the array.
The second line contains nn integers a1,a2,…,ana1,a2,…,an (0≤ai≤1090≤ai≤109).
Print the maximum number of segments the array can be divided into while following the given constraints. Print -1 if no suitable division exists.
4 5 5 7 2
2
3 1 2 3
-1
3 3 1 10
3
In the first example 22 is the maximum number. If you divide the array into {[5],[5,7,2]}{[5],[5,7,2]}, the XOR value of the subset of only the second segment is 5⊕7⊕2=05⊕7⊕2=0. {[5,5],[7,2]}{[5,5],[7,2]} has the value of the subset of only the first segment being 5⊕5=05⊕5=0. However, {[5,5,7],[2]}{[5,5,7],[2]} will lead to subsets {[5,5,7]}{[5,5,7]} of XOR 77, {[2]}{[2]} of XOR 22 and {[5,5,7],[2]}{[5,5,7],[2]} of XOR 5⊕5⊕7⊕2=55⊕5⊕7⊕2=5.
Let's take a look at some division on 33 segments — {[5],[5,7],[2]}{[5],[5,7],[2]}. It will produce subsets:
- {[5]}{[5]}, XOR 55;
- {[5,7]}{[5,7]}, XOR 22;
- {[5],[5,7]}{[5],[5,7]}, XOR 77;
- {[2]}{[2]}, XOR 22;
- {[5],[2]}{[5],[2]}, XOR 77;
- {[5,7],[2]}{[5,7],[2]}, XOR 00;
- {[5],[5,7],[2]}{[5],[5,7],[2]}, XOR 55;
As you can see, subset {[5,7],[2]}{[5,7],[2]} has its XOR equal to 00, which is unacceptable. You can check that for other divisions of size 33 or 44, non-empty subset with 00 XOR always exists.
The second example has no suitable divisions.
The third example array can be divided into {[3],[1],[10]}{[3],[1],[10]}. No subset of these segments has its XOR equal to 00.