给定两个01串a,b,|a| >= |b|。将b顺序与a的子串c比较,问有多少个f(b, c) is even。
最朴素的想法就是挨个比较,显然会TLE
肯定有什么巧妙的办法
kmp??不得行
我之前一直在想 记录b中每个字符与其前一个字符之间的关系 再xjb异或,或者搞个dp出来
最后把自己推翻了……这样xjb搞还不如之间暴力
……
直到今天我看到了题解
woc这么简单
如果f(b, c) is even,那么b中‘1‘的数量(记作cnt_b)和c中’1‘的数量(记作cnt_c)一定满足 (cnt_b + cnt_c) % 2 = 0,否则f(b, c) is even不成立。简单证xia明gao一下:
对于b,c对应相同的元素,只可能是00或者11,忽略它们(对cnt_b+cnt_c的奇偶性没有影响)
对于b,c对应相异的元素,只有可能是01(10),有多少对相异元素,就有多少个’1‘,即cnt_b+cnt_c与f(b, c)奇偶性相同
证毕
下面是超简单不到20行AC代码
#include<bits/stdc++.h>
#define MAXN 1000010
using namespace std;
char a[MAXN], b[MAXN];
int main(){
cin >> a >> b;
int len_a = strlen(a), len_b = strlen(b), cnt_a = 0, cnt_b = 0, cnt = 0;
for(int i = 0; i < len_b; i++){
cnt_b += (b[i] == '1');
cnt_a += (a[i] == '1');
}
for(int i = len_b; i < len_a; i++){
cnt += ((cnt_b + cnt_a) % 2 == 0);
cnt_a += (a[i] == '1') - (a[i - len_b] == '1');
}
cnt += ((cnt_b + cnt_a) % 2 == 0);
cout << cnt << endl;
return 0;
}