Educational Codeforces Round 81 B.

B.Infinite Prefixes


链接:https://codeforces.com/contest/1295/problem/B
【题意】
给一个长度为 n 的 0-1 字符串 Str ,找出所有Str的所有前缀子串中,满足 字符0个数 - 字符1个数 = x 的子串个数,输出答案,如果答案为无穷多则输出 “-1”
【思路】
sum[i] 是Str中01字符个数的差值的前缀和,即Str的前 i 个字符中, 字符0个数 - 字符1个数的个数
分类讨论:

  1. 首先考虑 "-1"的情况,如果sum[n] == 0,并且x的值在这个周期中(即sum[1]到sum[n])出现过,那么合法的答案就是无穷个,如果x没出现过答案就是 0
  2. 找到出整个周期,sum[i]值的变化量(即经历了一个周期后 sum[i]的变化),其实就是sum[n]。
    当满足
    ( x − s u m [ i ] ) / s u m [ n ] > = 0    a n d    ( x − s u m [ i ] ) m o d    s u m [ n ] = = 0 (x - sum[i])/sum[n] >= 0\ \ and\ \ (x -sum[i]) \mod sum[n] == 0 (xsum[i])/sum[n]>=0  and  (xsum[i])modsum[n]==0答案就可以加一
    其意义为某个位置的前缀和加上n个周期的贡献为x,同时要保证周期次数大于等于0次
/*****************************
*author:ccf
*source:cf_ER 81 B. Infinite Prefixes
*topic:
*******************************/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#define ll __int64
using namespace std;

const int N = 1e5+7;
ll n,cas,x;

int main(){
	freopen("data.in","r",stdin);
	scanf("%I64d",&cas);
	char str[N];
	ll sum[N],ans,flag; 
	while(cas--){
		scanf("%I64d %I64d",&n,&x);
		scanf("%s",str+1);
		memset(sum,0,sizeof sum);
		ans= 0,flag = 0;
		for(int i = 1; i <= n; ++i){
			if(str[i] == '0') sum[i] = sum[i-1]+1;
			else sum[i] = sum[i-1]-1;
			if(sum[i] == x) flag = 1;
		}
		if(x == 0) ++ans;
		if(sum[n] == 0){
			if(flag) printf("-1\n");
			else printf("%I64d\n",ans);
			continue;
		}
		for(int i = 1; i <= n; ++i)
			if((x - sum[i])/sum[n] >= 0 && (x -sum[i]) % sum[n] == 0) ans++;
		printf("%I64d\n",ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值