zoukankan      html  css  js  c++  java
  • 子段异或(位运算)

    链接:https://ac.nowcoder.com/acm/contest/3005/D
    来源:牛客网

    题目描述

    输入一个数列a,你需要输出其中异或值为0的不同子段的数量。
    一个子段 [l,r] (1≤l≤r≤n)的异或值为alal+1al+2ar,其中符号代表异或运算
    两个子段被视为相同的,当且仅当其开始和结束位置均对应相同。

    输入描述:

    第一行一个整数 n ,代表数列长度。
    第二行 n 个整数,代表数列。

    输出描述:

    输出一个整数,代表答案。

    输入

    5
    1 2 3 2 1

    输出

    2

    说明

    子段 [1,3] 和子段 [3,5] 是合法子段。

    备注:

    n≤200000,0≤ai≤230−1

    [l,r]=a[l]a[l+1]...a[r1]a[r]

    [1,l-1]=a[1]a[2]...a[l2]a[l1]

    [1,r]=a[1]a[2]...a[r1]a[r]

    所以有:[1,l1][1,r]=[l,r]

    所以预处理出所有的前缀异或和即可,由于需要[l,r]=0,故[1,l-1]=[1,r]

    如a[0]^...^a[i]的亦或前缀和与a[0]^...^a[i+k]的亦或前缀和相等,则a[i+1]^...^a[i+k]=0

    配合map比较好

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <stack>
     9 #include <queue>
    10 #include <set>
    11 #include <map>
    12 #include <sstream>
    13 const int INF=0x3f3f3f3f;
    14 typedef long long LL;
    15 const int mod=1e9+7;
    16 const int maxn=2e5+10;
    17 using namespace std;
    18 
    19 int sum[maxn];
    20 map<int,int> mp;
    21 
    22 int main()
    23 {
    24     #ifdef DEBUG
    25     freopen("sample.txt","r",stdin);
    26     #endif
    27     
    28     int n;
    29     scanf("%d",&n);
    30     LL ans=0;//记得开long long 
    31     mp[0]++;
    32     for(int i=1;i<=n;i++)
    33     {
    34         int x;
    35         scanf("%d",&x);
    36         sum[i]=sum[i-1]^x;
    37         if(mp.count(sum[i]))//如果该前缀和之前出现过 
    38             ans+=mp[sum[i]];
    39         mp[sum[i]]++;
    40     }
    41     printf("%lld
    ",ans);
    42     
    43     return 0;
    44 }

    -

  • 相关阅读:
    Java debug技术
    mybatis-generator插件
    JVM常见问题
    Java安全之Access control
    JVM新生代各个区的比例问题
    宣告
    退役啦!
    NOIP 2018退役祭
    自定义博客园模板
    带花树算法
  • 原文地址:https://www.cnblogs.com/jiamian/p/12300815.html
Copyright © 2011-2022 走看看