**
B. Infinite Prefixes
**
time limit per test2 seconds
memory limit per test256 megabytes
You are given string 𝑠 of length 𝑛 consisting of 0-s and 1-s. You build an infinite string 𝑡 as a concatenation of an infinite number of strings 𝑠, or 𝑡=𝑠𝑠𝑠𝑠… For example, if 𝑠=10010, then 𝑡=100101001010010…
Calculate the number of prefixes of 𝑡 with balance equal to 𝑥. The balance of some string 𝑞 is equal to 𝑐𝑛𝑡0,𝑞−𝑐𝑛𝑡1,𝑞 are 𝑐𝑛𝑡0,𝑞 is the number of occurrences of 0 in 𝑞, and 𝑐𝑛𝑡1,𝑞 is the number of occurrences of 1 in 𝑞. The number of such prefixes can be infinite; if it is so, you must say that.
A prefix is a string consisting of several first letters of a given string, without any reorders. An empty prefix is also a valid prefix. For example, the string “abcd” has 5 prefixes: empty string, “a”, “ab”, “abc” and “abcd”.
Input
The first line contains the single integer 𝑇 (1≤𝑇≤100) — the number of test cases.
Next 2𝑇 lines contain descriptions of test cases — two lines per test case. The first line contains two integers 𝑛 and 𝑥
(1≤𝑛≤105, −109≤𝑥≤109) — the length of string 𝑠 and the desired balance, respectively.
The second line contains the binary string 𝑠 (|𝑠|=𝑛, 𝑠𝑖∈{0,1}).
It’s guaranteed that the total sum of 𝑛 doesn’t exceed 105.
Output
Print 𝑇 integers — one per test case. For each test case print the number of prefixes or −1 if there is an infinite number of such prefixes.
Note
In the first test case, there are 3 good prefixes of 𝑡: with length 28, 30 and 32.
官方题解:
https://codeforces.com/blog/entry/73467
Let’s denote a prefix of length 𝑖 as 𝑝𝑟𝑒𝑓(𝑖). We can note that each 𝑝𝑟𝑒𝑓(𝑖)=𝑘⋅𝑝𝑟𝑒𝑓(𝑛)+𝑝𝑟𝑒𝑓(𝑖mod𝑛) where 𝑘=Math.floor(i/n)(向下取整)
and + is a concatenation. Then balance 𝑏𝑎𝑙(𝑖) of prefix of length 𝑖 is equal to 𝑘⋅𝑏𝑎𝑙(𝑛)+𝑏𝑎𝑙(𝑖mod𝑛).
pref(i)表示长度为i的前缀.
bal(i)表示长度为i的前缀的余数,数值上等于𝑘⋅𝑏𝑎𝑙(𝑛)+𝑏𝑎𝑙(𝑖mod𝑛).
Now there two cases:
(1)𝑏𝑎𝑙(𝑛) is equal to 0 or not. If 𝑏𝑎𝑙(𝑛)=0 then if exist such 𝑗 (0≤𝑗<𝑛) that 𝑏𝑎𝑙(𝑗)=𝑥 then for each 𝑘≥0 𝑏𝑎𝑙(𝑗+𝑘𝑛)=𝑥 and answer is −1.
当给的二进制字符串0和1的数量相等时,那么前缀可能有0个或者无数个.
若有无数个符合要求的前缀输出-1.
如果当给定的字符串第j个位置bal==x,表示在每连上一个字符串,𝑏𝑎𝑙(𝑗+𝑘𝑛)=0+bal(j)=𝑥 .此时将会有无数个前缀.
(2)Otherwise, for each such 𝑗 there will no more than one possible 𝑘: since there are zero or one solution to the equation 𝑏𝑎𝑙(𝑗)+𝑘⋅𝑏𝑎𝑙(𝑛)=𝑥. The solution exists if and only if 𝑥−𝑏𝑎𝑙(𝑗)≡0 mod 𝑏𝑎𝑙(𝑛) and 𝑘=
( 𝑥−𝑏𝑎𝑙(j) ) / 𝑏𝑎𝑙(𝑛) ≥0. So, just precalc 𝑏𝑎𝑙(𝑛) and for each 0≤𝑗<𝑛 check the equation.
当给定的二进制字符串0和1的数量不相等的时候,可能会有0或1个解.
有解(一个解)的条件:1⃣️j位置的cnt=cnt(0)-cnt(1)与x的差可以整除整个字符串的cnt差.2⃣️( 𝑥−𝑏𝑎𝑙(j) ) 与 𝑏𝑎𝑙(𝑛) 同号.不同号的话会随着字符串的增加使得答案越来越远.
此处≡表示同余符号.数论中的重要概念。给定一个正整数m,如果两个整数a和b满足a-b能够被m整除,即(a-b)/m得到一个整数,那么就称整数a与b对模m同余,记作a≡b(mod m)。对模m同余是整数的一个等价关系。𝑥−𝑏𝑎𝑙(𝑗)≡0 mod 𝑏𝑎𝑙(𝑛)等价于( 𝑥−𝑏𝑎𝑙(𝑗)-0 ) mod 𝑏𝑎𝑙(𝑛).
题意:
统计余数为x的前缀串的数量.
import java.util.Scanner;
public class Main{
public static int n,x;
// public static int []a=new int[100000];
public static String s;
public static void Solve() {
int ans=0;
boolean infAns=false;
int cntZeros=0;
for(int i=0;i<n;i++) {
if(s.charAt(i)=='0') {
cntZeros++;
}
}
int total=cntZeros-(n-cntZeros);
int bal=0;
for(int i=0;i<n;i++) {
if(total==0) {
if(bal==x) {
infAns=true;
}
}else if(Math.abs(x-bal)%Math.abs(total)==0) {
if((x-bal)/total>=0) {
ans++;
}
}
if(s.charAt(i)=='0') {
bal++;
}else {
bal--;
}
}
if(infAns)ans=-1;
System.out.println(ans);
}
public static void main(String[]args) {
Scanner sc=new Scanner(System.in);
int T=sc.nextInt();
while(T-->0) {
n=sc.nextInt();
x=sc.nextInt();
s=sc.next();
Solve();
}
}
}