https://vjudge.net/problem/CodeForces-1295B
题目大意:给定一个长度为
n
n
n的
01
01
01串,设其为
s
s
s,那么字符串
t
=
s
s
s
s
…
…
t=ssss……
t=ssss……,设一个字符串
q
q
q的平衡值为
c
n
t
0
−
c
n
t
1
cnt_0-cnt_1
cnt0−cnt1,其中
c
n
t
0
cnt_0
cnt0为字符串
q
q
q中
0
0
0的个数,
c
n
t
1
cnt_1
cnt1为字符串
q
q
q中
1
1
1的个数,现在给定字符串
s
s
s和一个值
x
x
x,问字符串
t
t
t的前缀中平衡值等于
x
x
x的前缀个数,如果这样的前缀有无穷多个,那么输出
−
1
-1
−1。
思路:设字符串
s
s
s的前缀
s
i
s_i
si的平衡值为
v
i
v_i
vi,那么字符串
t
t
t的前缀的平衡值为:
v
1
,
v
2
,
v
3
,
…
…
,
v
n
v_1,v_2,v_3, ……,v_n
v1,v2,v3,……,vn
v
n
+
v
1
,
v
n
+
v
2
,
v
n
+
v
3
,
…
…
,
2
∗
v
n
v_n+v_1,v_n+v_2,v_n+v_3,……,2*v_n
vn+v1,vn+v2,vn+v3,……,2∗vn
2
∗
v
n
+
v
1
,
2
∗
v
n
+
v
2
,
2
∗
v
n
+
v
3
,
…
…
,
3
∗
v
n
2*v_n+v_1,2*v_n+v_2,2*v_n+v3,……,3*v_n
2∗vn+v1,2∗vn+v2,2∗vn+v3,……,3∗vn
不难发现,如果平衡值等于
x
x
x的前缀个数有无穷多个,那么必定有
v
n
=
0
v_n=0
vn=0,否则解一定是有限的。对于前缀
s
i
s_i
si,如果满足
(
x
−
v
i
)
%
v
n
=
0
(x-v_i)\%v_n=0
(x−vi)%vn=0且
x
−
v
i
x-v_i
x−vi和
v
n
v_n
vn同号,那么
s
i
s_i
si就对答案有贡献。当然还有一种特殊情况我们没有考虑到,就是前缀为空字符串的时候,当且仅当
x
=
0
x=0
x=0时空字符串才对答案有贡献。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
char s[maxn];
int v[maxn];
int main()
{
int t,n,x;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%s",&n,&x,s+1);
int len=strlen(s+1);
int cnt1=0,cnt2=0;
bool flag=0;
for(int i=1;i<=len;i++)
{
if(s[i]=='1')
++cnt1;
else
++cnt2;
v[i]=cnt2-cnt1;
if(v[i]==x)
flag=1;
}
if(x==0)
flag=1;
if(v[n]==0)
{
if(flag)//平衡值等于x的前缀存在 则有无穷多个
printf("-1\n");
else //前缀不存在 那么答案自然为0
printf("0\n");
}
else
{
int ans=0;
if(x==0)//前缀为空字符串时仅对x=0有贡献
++ans;
for(int i=1;i<=len;i++)
if((x-v[i])%v[n]==0&&(x>=v[i]&&v[n]>0||x<=v[i]&&v[n]<0))
++ans;
printf("%d\n",ans);
}
}
return 0;
}