C. Vus the Cossack and Strings

https://codeforces.com/problemset/problem/1186/C

题目描述

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| \leq |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 bb and 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) .

For example, let b = 00110b=00110 , and c = 11000c=11000 . In these strings, the first, second, third and fourth positions are different.

Vus the Cossack counts the number of such substrings cc such that f(b, c)f(b,c) is even.

For example, let a = 01100010a=01100010 and b = 00110b=00110 . aa has four substrings of the length |b|∣b∣ : 0110001100 , 1100011000 , 1000110001 , 0001000010 .

  • 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 .

Vus can not find the answer for big strings. That is why he is asking you to help him.

输入格式

The first line contains a binary string aa ( 1 \leq |a| \leq 10^61≤∣a∣≤106 ) — the first string.

The second line contains a binary string bb ( 1 \leq |b| \leq |a|1≤∣b∣≤∣a∣ ) — the second string.

输出格式

Print one number — the answer.

题意翻译

给定两个由0,10,1构成的字符串aa和bb,其中|b|\leq |a|.∣b∣≤∣a∣.

对于aa的某个长度为|b|∣b∣的字串cc,记对应位不同的字符数为f(b, c).f(b,c).

如:当b=00110,c=11000b=00110,c=11000时,f(b, c) = 4,f(b,c)=4,其中第1,2,3,41,2,3,4位不同。

求所有cc中f(b,c)f(b,c)为偶数的个数。

输入输出样例

输入 #1复制

01100010
00110

输出 #1复制

3

输入 #2复制

1010111110
0110

输出 #2复制

4

说明/提示

The first example is explained in the legend.

In the second example, there are five substrings that satisfy us: 10101010 , 01010101 , 11111111 , 11111111 .


这道题说实话没想到,考了个奇数偶数性。

其实暴力优化想不出来。看样例没准可以莽一波。当然以后碰到cf的构造或者奇怪思路题不妨多往奇偶性想。

但是练习的时候要尽量弄懂这题为啥阿?

不妨设 b 串有 m 个 1 , c 串有 n 个 1 ,且 b 、 c 中同为 1 的位置数为 k 。那么 b, c 中字符不同的位置数有 cnt=m−k+n−k=m+n−2*k 。

例如: 1 1 1 0 0 0  [m个1]

            0 0 1 1  1 1 [n个1]

那么cnt=m-k+n-k  

由题目条件要求cnt为偶数的时候统计。因此当 m+n 为偶数时, cnt 为偶数.

所以只要m和n同时为奇数或者同时为偶数就可以了。那用前缀和预处理a串中的1的数量,枚举的时候O(1)查询c串区间内1的数量,看看是不是和b串的1的数量是同奇偶的。

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e6+1000;
typedef long long LL;
char a[maxn],b[maxn];
LL sum[maxn];
void solve()
{
	LL alen=strlen(a+1);
	LL blen=strlen(b+1);
	for(LL i=1;i<=alen;i++){
		sum[i]=sum[i-1]+(a[i]=='1');
	}
	LL cnt1=0;
	for(LL i=1;i<=blen;i++){
		if(b[i]=='1') cnt1++;
	} 
	LL ans=0;
	for(LL i=1;i<=alen-blen+1;i++)
	{
		if ( ( (sum[i+blen-1]-sum[i-1])+cnt1)%2==0)
		{
			ans++;
		}
	}
	cout<<ans<<endl;
} 
int main(void)
{
  cin>>a+1;
  cin>>b+1;
  solve();
return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值