CF1658F Juju and Binary String

首先一个自然的想法(虽然我自己没想到),设 \(A\) 为串中 \(1\) 的个数, \(B\) 为串中 \(0\) 的个数,那么如果每个 \(1\) 的价值是 \(-B\), \(0\) 的价值是 \(A\) 那么价值和为 \(0\) 的序列可爱度和原串一样。
这个很显然,不需要证明。
这时候有一个很牛逼的性质,就是答案只为 \(1\)\(2\)
因为如果将序列看成环上序列,那么每一次 \(1\) 的变化量至多为 \(1\),如果每个长度为 \(m\) 的序列都不满足,那一定没有答案,反之有解且最终一定可以逼近到解。

Tips:
分数相等的形式可以对位相乘,便于处理。
大胆猜测。

#include<bits/stdc++.h>
#define RG register
#define LL long long
#define U(x, y, z) for(RG int x = y; x <= z; ++x)
#define D(x, y, z) for(RG int x = y; x >= z; --x)
using namespace std;
void read(){}
template<typename _Tp, typename... _Tps>
void read(_Tp &x, _Tps &...Ar) {
	x = 0; char ch = getchar(); bool flg = 0;
	for (; !isdigit(ch); ch = getchar()) flg |= (ch == '-');
	for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
	if (flg) x = -x;
	read(Ar...);	
}
inline char Getchar(){ char ch; for (ch = getchar(); !isalpha(ch); ch = getchar()); return ch;}
template <typename T> inline void write(T n){ char ch[60]; bool f = 1; int cnt = 0; if (n < 0) f = 0, n = -n; do{ch[++cnt] = char(n % 10 + 48); n /= 10; }while(n); if (f == 0) putchar('-'); for (; cnt; cnt--) putchar(ch[cnt]);}
template <typename T> inline void writeln(T n){write(n); putchar('\n');}
template <typename T> inline void writesp(T n){write(n); putchar(' ');}
template <typename T> inline void chkmin(T &x, T y){x = x < y ? x : y;}
template <typename T> inline void chkmax(T &x, T y){x = x > y ? x : y;}
template <typename T> inline T Min(T x, T y){return x < y ? x : y;}
template <typename T> inline T Max(T x, T y){return x > y ? x : y;}
inline void readstr(string &s) { s = ""; static char c = getchar(); while (isspace(c)) c = getchar(); while (!isspace(c)) s = s + c, c = getchar();}
inline void FO(string s){freopen((s + ".in").c_str(), "r", stdin); freopen((s + ".out").c_str(), "w", stdout);}

const int N = 2e5 + 10;
char s[N];
int a[N], sum[N];

inline void solve() {
	int n, m;
	read(n, m);
	scanf("%s", s + 1);
	int A, B;
	A = B = 0;
	U(i, 1, n) if (s[i] == '0') ++A; else --B;
	U(i, 1, n) if (s[i] == '0') a[i] = B; else a[i] = A;
	U(i, 1, n) sum[i] = sum[i - 1] + a[i];
	U(i, m, n) if (sum[i] - sum[i - m] == 0) {
		puts("1");
		writesp(i - m + 1), writeln(i);
		return ;
	}
	U(i, 1, m - 1) {
		if (sum[i] + sum[n] - sum[n - (m - i)] == 0) {
			puts("2");
			writesp(1), writeln(i);
			writesp(n - (m - i) + 1), writeln(n);
			return ;
		}
	}
	puts("-1");
}

int main(){
	//FO("");
	int T;
	read(T);
	while (T--) solve();
	return 0;
}
posted @ 2022-11-25 17:12  Southern_Way  阅读(24)  评论(0)    收藏  举报