题解:CF1979D Fixing a Binary String
因为
-
\underbrace{11\cdots1}_{k \ 个 \ 1} \underbrace{00\cdots0}_{k \ 个 \ 0} \cdots -
\underbrace{00\cdots0}_{k \ 个 \ 0} \underbrace{11\cdots1}_{k \ 个 \ 1} \cdots
题目已经告诉我们,若选择的位置为
判断字符串相等可以哈希维护。
维护原序列的哈希和反转后的序列的哈希,以
如果你不明白为什么拼起来哈希值是它。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
#ifdef ONLINE_JUDGE
#define debug(...) 0
#else
#define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#endif
using ull = unsigned long long;
const int N = 1e5 + 5;
ull base = 233;
int n, k;
char s[N], revs[N];
char v1[N], v2[N];
inline char rev(char x) {return x == '0' ? '1' : '0';}
ull pre[N], suf[N];
ull pw[N];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
pw[0] = 1;
for (int i = 1; i < N; i++) pw[i] = pw[i - 1] * base;
int tt;
cin >> tt;
while (tt--) {
cin >> n >> k >> s + 1;
for (int i = 1; i <= k; i++) v1[i] = '1', v2[i] = '0';
for (int i = k + 1; i <= n; i++) v1[i] = rev(v1[i - k]), v2[i] = rev(v2[i - k]);
int cnt = count(s + 1, s + 1 + n, '1');
ull h1 = 0, h2 = 0;
int t1 = 0, t2 = 0;
for (int i = 1; i <= n; i++) {
h1 = h1 * base + v1[i], t1 += v1[i] == '1';
h2 = h2 * base + v2[i], t2 += v2[i] == '1';
}
if (t1 != cnt) h1 = -1;
if (t2 != cnt) h2 = -1;
strcpy(revs + 1, s + 1);
reverse(revs + 1, revs + 1 + n);
pre[0] = suf[0] = 0;
for (int i = 1; i <= n; i++) {
pre[i] = pre[i - 1] * base + s[i];
suf[i] = suf[i - 1] * base + revs[i];
}
int ans = -1;
for (int i = 1; i <= n; i++) {
ull h = (pre[n] - pre[i] * pw[n - i]) * pw[i] + (suf[n] - suf[n - i] * pw[i]);
if (h == h1 || h == h2) {
ans = i;
break;
}
}
cout << ans << "\n";
}
return 0;
}
样例第四个小点答案