Educational Codeforces Round 81 Editorial

**

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();
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值