Xor and Sum(異或和+算術和)


 

題目描述

給定一個大小為N的數組A,第i個元素為Ai。

問有多少的子區間[LR],滿足區間數值異或和等於區間數值和,即:

     Al xor Al+1 xor…xor Ar = Al + Al+1 +…+Ar(l+1表示下標)
      a和b的xor即為a和b二進制表示按位取xor得到新數c的十進制表示
5和12的xor計算如下:

510=01012

(12)10=(1100)2

01012xor11002=(1001)2

(1001)2=(9)10

輸入

第一行給定一個整數N。
第二行給定N個整數,第i個數即為Ai。
1≤N≤2×10^5
0≤A_i≤2^30

輸出

輸出滿足條件的子區間LR的數量。

樣例輸入

10
0 0 740 361 473 0 0 826 479 974


樣例輸出

18

 

 

題解:

xor運算可以視為二進制下沒有進位的加法,加法運算本身是有進位的加法。

那么可以簡單得出這樣一個性質:對於一個區間而言,如果異或和加法答案一樣,那么把區間縮小答案肯定還是一樣;如果異或和加法答案不一樣,那么把區間擴大答案肯定還是不一樣。

於是我們就可以枚舉區間右端點,去尋找最小的左端點,這個區間異或等於區間和,那么以這個區間右端點的合法區間個數就是區間的長度(左端點往里縮都是合法的)。

這個可以預處理出前綴和還有前綴異或和,用雙指針維護出來。

 

 

 

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<stdio.h>
 4 #include<string.h>
 5 #include<string>
 6 #include<queue>
 7 #include<stdlib.h>
 8 #include<math.h>
 9 #define per(i,a,b) for(int i=a;i<=b;++i)
10 #define rep(i,a,b) for(int i=a;i>=b;--i)
11 #define inf 0xf3f3f3f
12 #define ll long long int 
13 using namespace std;
14 int p[200005];
15 int s[200005];
16 int z[200005];
17 int main()
18 {
19     int m,a;
20     cin>>m;
21     z[0]=0;s[0]=0;
22     per(i,1,m) 
23     {
24         cin>>a;
25         s[i]=s[i-1]+a;
26         z[i]=z[i-1]^a;
27     }
28     ll l=0,sum=0;
29     per(i,1,m)
30     {
31         while((z[i]^z[l])!=(s[i]-s[l])) l++;
32         sum+=i-l;
33     }
34     cout<<sum;
35     return 0;
36 }

 

 

 

 

 

 

 

-


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM