C. Vus the Cossack and Stringsc++
Vus the Cossack has two binary strings, that is, strings that consist only of "0" and "1". We call these strings aa and bb. It is known that |b|≤|a||b|≤|a|, that is, the length of bb is at most the length of aa.數組
The Cossack considers every substring of length |b||b| in string aa. Let's call this substring cc. He matches the corresponding characters in bband cc, after which he counts the number of positions where the two strings are different. We call this function f(b,c)f(b,c).ide
For example, let b=00110b=00110, and c=11000c=11000. In these strings, the first, second, third and fourth positions are different.this
Vus the Cossack counts the number of such substrings cc such that f(b,c)f(b,c) is even.spa
For example, let a=01100010a=01100010 and b=00110b=00110. aa has four substrings of the length |b||b|: 0110001100, 1100011000, 1000110001, 0001000010.code
- f(00110,01100)=2f(00110,01100)=2;
- f(00110,11000)=4f(00110,11000)=4;
- f(00110,10001)=4f(00110,10001)=4;
- f(00110,00010)=1f(00110,00010)=1.
Since in three substrings, f(b,c)f(b,c) is even, the answer is 33.blog
Vus can not find the answer for big strings. That is why he is asking you to help him.three
The first line contains a binary string aa (1≤|a|≤1061≤|a|≤106) — the first string.ci
The second line contains a binary string bb (1≤|b|≤|a|1≤|b|≤|a|) — the second string.字符串
Print one number — the answer.
01100010 00110
3
1010111110 0110
4
The first example is explained in the legend.
In the second example, there are five substrings that satisfy us: 10101010, 01010101, 11111111, 11111111.
題意:題目給了一個較長字符串a以及一個較短字符串b,在a中取與b長度相等的子串,比較子串與b字符串中有幾組字符不同。
當天下午因爲在探討研究這場CF B題的4 4 狀況,而致使後來沒怎麼看這道題,但實際上這道題對於位運算的運用是十分的基礎並且有效的。
順帶一提,B題4 4的狀況,不只hack掉了基本全部的AC代碼,甚至讓這場比賽都不算rate了
先科普一下 位運算中的 異或(運算符"^"),在二進制中,若是兩個數字相同的話,那麼異或的結果就是0,不然就是1;同時兩次異或同一個數字,就至關於沒有沒有異或過這個數字
先貼一下代碼
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int inf = 0x3f3f3f3f; 5 const int maxn = 2000030; 6 char a[maxn],b[maxn]; 7 int ans = 0,sum = 0; 8 int main(){ 9 scanf("%s",a); 10 scanf("%s",b); 11 int len_a = strlen(a); 12 int len_b = strlen(b); 13 for(int i = 0 ; i < len_b ; i++){ 14 ans=ans^a[i]^b[i]; 15 } 16 if(ans%2 == 0) sum++; 17 for(int i = len_b ; i < len_a ; i++){ 18 ans = ans^a[i-len_b]^a[i]; 19 if(ans % 2 == 0) sum++; 20 } 21 printf("%d\n",sum); 22 return 0; 23 }
例如,樣例一:
一開始先對於 i = 0 到 i = strlen(b) 中 b 字符串和a的子串進行異或操做,若是異或結果(ans)能夠整除2,那麼就表明這個子串對於b而言有偶數組不一樣。
以後就能夠有i = len 向 i = strlen(a)中逐位挪移,而計算結果就是 新的 ans = 舊的 ans ^ a[i - len] ^ a[i])。^a[i - len]就是消除a[i - len]的影響,^a[i]就是將a[i]的影響加入計算
一開始的狀態
(0^0)^(1^0)^(1^1)^(0^1)^(0^0)
向右挪移一位
(0^0)^(1^0)^(1^1)^(0^1)^(0^0)^0^0 // 第一個0 是a[i - len],第二個0是a[i];
= 0^(0^0)^(1^0)^(1^1)^(0^1)^(0^0)^0 // 由於一個數字異或兩次至關於沒有異或
= ·(0^1)^(0^1)^(1^0)^(1^0)^(0^0)
這樣只須要O(n)的時間複雜度就能夠完成運算。
一個從好久之前就開始作的夢。