Codeforces 1186C. Vus the Cossack and Strings【前缀和】【规律】

题目链接

题意

给你两个字符串a,b,字符全由0和1组成;b的长度小于等于a的长度,对于a的所有长度大于b的子串c,
f(b,c)的表示b,c中不同字符的个数;我们的任务时就是找出a的所有子串c和b的 f(b,c) 的值为偶数的子串个数

思路

如果b = 00000,则c中有几个1则 f(b,c) 就是几,如果有偶数个1则符合我们要找的一个子串,奇数则不符合;
如果b = 01000,
则 c = 10000,
c = 01000,
c = 01110,
c = 11111,
……
以上的c都是符合条件的,而他们的1的数量都是奇数,而在1的数量为偶数时是不符合的,即01100,011110,
模拟一下b中1为偶数的情况,我们就可以发现当b中1为偶数,则c中的1也要为偶数才符合条件,如果b中1为奇数,那么c中的1也要为奇数才符合条件;
得到这个结论,我们就可以用一个前缀和数组求出a中的1的数量,和b中1的数量进行比较即可

代码

#include <bits/stdc++.h>
using namespace std;

char a[1000100], b[1000100];
int c[1000100];
int main(){
	a[0] = '&', b[0] = '&';
	scanf("%s%s", a+1, b+1);
	int lena = strlen(a);
	int lenb = strlen(b), cnt = 0;
	for(int i = 1; i < lenb; i++){
		if(b[i] == '1'){
			cnt++;
		}
	}
	for(int i = 1; i < lena; i++){
		if(a[i] == '1'){
			c[i] = c[i-1] + 1;
		}
		else{
			c[i] = c[i-1];
		}
	}
	int ans = 0;
	for(int i = 1; i + lenb - 2 < lena; i++){
		int q = c[i+lenb-2] - c[i-1];
		if(q % 2 && cnt % 2){
			ans++;
		}
		if(q % 2 == 0 && cnt % 2 == 0){
			ans++;
		}
	}
	cout << ans << endl;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值