2020牛客寒假算法基础集训营4D.子段异或(位运算)

连接:https://ac.nowcoder.com/acm/contest/3005/Dios

 

题意:数组

给一个数组,问有多少个子序列的异或和为0spa

思路:code

首先咱们须要一个定义一个前缀和数组sum[i],表明从1到i这段的异或和blog

那么神奇的事情来了,sum[l-r]=sum[l-1]^sum[r],由于他们相同的部分异或起来为0,这也是与普通前缀和不一样的部分ci

若是这段的异或和为0,那么sum[l-1]^sum[r]=0,也就是sum[l-1]=sum[r],所以咱们只须要统计每一个前缀和的数值,看有多少前缀和相同get

最后答案就为∑cnti*(cnti-1)it

#include<iostream>
#include<algorithm>
#include<map>
 using namespace std;
 const int maxn=2e5+10;
 typedef long long ll;
 ll a[maxn];
 map<ll,ll> s;
 int main()
 {
     ll ans=0,n,sum=0;
     cin>>n;
     s[0]=1;
     for(int i=1;i<=n;i++){
         scanf("%lld",&a[i]);
         sum^=a[i];
         ans+=s[sum];
         s[sum]+=1;
     }
    cout<<ans<<endl;
    return 0;
 }
相关文章
相关标签/搜索