题目链接:https://ac.nowcoder.com/acm/contest/553/G
题意:给定n,k,(1<=n<=5e5)然后给出n个数ai(1<=ai<=1e5),问按顺序从1..n分组,最多能有多少个组的异或和为k。
思路:自然的,我们用dp[i]表示到第i个人的时候最多有多少个组的异或和为k。计算dp[i]时,有两种情况,要么在第i个人后面分出一组,要么不分。不分的话dp[i]=dp[i-1]就可以了; 如果分得话,就要找到上一个组的终点下标,我们可以计算到第i个人时的异或和sum,显然可由此得到上一个组终点处的sum‘,sum’=sum^k,所以我们用一个数组pre[j]表示sum为j时的最后一个下标(初始化为-1),最后的dp[n]即为所求。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=500005; 5 int n,k,dp[maxn],sum,pre[maxn]; 6 7 int main(){ 8 memset(pre,-1,sizeof(pre)); 9 pre[0]=0; 10 scanf("%d%d",&n,&k); 11 int tmp; 12 for(int i=1;i<=n;++i){ 13 scanf("%d",&tmp); 14 sum^=tmp; 15 if(pre[sum^k]!=-1) 16 dp[i]=max(dp[i-1],dp[pre[sum^k]]+1); 17 else 18 dp[i]=dp[i-1]; 19 pre[sum]=i; 20 } 21 printf("%d ",dp[n]); 22 return 0; 23 }