[ABC 098] D-Xor Sum 2

D - Xor Sum 2


Time limit : 2sec / Memory limit : 1024MB

Score : 500 points

Problem Statement

There is an integer sequence A of length N.

Find the number of the pairs of integers l and r (1≤lrN) that satisfy the following condition:

  • Al xor Al+1 xor … xor Ar=Al + Al+1 + … + Ar

Here, xor denotes the bitwise exclusive OR.

Definition of XOR

Constraints

  • 1≤N≤2×105
  • 0≤Ai<220
  • All values in input are integers.

[题目解释]

  给你一个长度为N(1≤N≤2×105)的整数序列,寻找是否存在一对整数l,r(1≤l≤r)使Al xor Al+1 … xor Ar =Al+Al+1…+Ar (xor 的意思是异或),统计这样的整数个数

[题目解析]

  由于我们不知道每个r是否存在与其配对的整数l使区间(l,r)的异或之和等于数值之和,于是我们很容易想到O(n2)的做法对于每个r我们都动态查找r左边是否存在一个l使上列式子成立,若成立记入进ans中.可是这样的做法显然是不够优秀的,于是我们可以从这个不常见的运算异或xor(c++中可用'^'表示),我们发现xor有个别称'不进位的加法'(二进制下舍弃进位的加法)我们发现已知存在一个区间(l,r)满足上述式子,那么如果l~r之间存在进位那么异或之和一定会比数值之和小,便不成立上述式子了,于是我们发现如果l~r成立那么l+1~r也成立,对于每个r我们只要找到与其配对的最小l就可以计算r的所有符合题意的整数对.怎么快速地找到l呢?我们发现如果一对整数(l,r),(l,r+1)如果成立l的最大数值便是l,如果不成立那么与r+1配对的l必定大于(l,r)中的l(l是只增不减的),于是我们便把时间复杂度降到了O(n)

[代码]

/*
    Name: Xor Sum 2 
    Author: FZSZ-LinHua
    Date: 2018 06 07
    Exec time: 13ms
    Memory usage: 1664KB
    Score: 500
    Algorithm: Brute-force 
*/
# include "cstdio"

const int maxm=200000+10; 

int 
    a[maxm],   //加法前缀和 
    b[maxm],   //减法前缀和 
    n; //一共n个数
     
long long 
    ans;   //答案 

inline int read(){  //快速读入 
    int s=0,w=1;
    char ch=getchar();
    while(ch<'0' || ch>'9'){
        if(ch=='-') w=-w;
        ch=getchar();
    }
    while(ch>='0' && ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*w;
}

int main(){
    n=read(); 
    register int i,j;
    for(i=1;i<=n;i++){
        j=read();
        a[i]=j+a[i-1];    //计算加法前缀和 
        b[i]=j^b[i-1];    //计算异或前缀和 
    }
    for (i=j=1;i<=n;i++){
         for(;a[i]-a[j-1]!=(b[i]^b[j-1]);j++);
         //计算l的最小合法数值 
         ans+=i-j+1;    //(l,r)中一共l-r+1种(l~r,l+1~r,l+2~r…) 
    }
    printf("%lld",ans);
    return 0; 
} 

猜你喜欢

转载自www.cnblogs.com/FJ-LinHua/p/9148879.html