#ifdef LOCAL #include"algo/debug.h" #else #define debug(...) 42 #endif
intmain(){ ios::sync_with_stdio(false); cin.tie(0); int tt; cin >> tt; while (tt--) { int n; cin >> n; string s; cin >> s; int mx = 1; int t = 1; for (int i = 1; i < n; i++) { if (s[i] == s[i - 1]) { t += 1; mx = max(mx, t); } else { t = 1; } } int x = 0; for (int i = 0; i < n; i++) { x += (s[i] == '0'); } int y = n - x; longlong ans = (longlong) x * y; ans = max(ans, (longlong) mx * mx); cout << ans << '\n'; } return0; }
C. Complementary XOR
题意:有两个 01 串 a,b,每次操作可以选一个区间,将 a 这段区间内的元素取反, b 这段元素外的区间取反。构造一种方案,在 n+5 次操作内将两个串归零,或判断无解。
容易发现,进行操作后 a,b 的异或值将会完全取反,所以只有当 a=b 或 a=inv(b) 时才可能有解。如果 a=inv(b),我们可以先选整个串,将 a 取反,转化为 a=b 的情况。此后,当奇数次操作后 a=inv(b),偶数次操作后 a=b。问题转化为:每次可以选 a 的一段区间取反,恰好偶数次操作内将 a 归零。
intmain(){ ios::sync_with_stdio(false); cin.tie(0); int tt; cin >> tt; while (tt--) { int n, m; cin >> n >> m; vector<int> a(n); for (int i = 0; i < n; i++) { cin >> a[i]; } Mint ans = 1; for (int i = 0; i < n - 1; i++) { int x = a[i]; int y = a[i + 1]; if (x % y != 0) { ans = 0; break; } if (x == y) { ans *= m / x; continue; } int bound = m / y; int num = x / y; vector<int> fs; for (int j = 2; j * j <= num; j++) { if (num % j == 0) { fs.push_back(j); while (num % j == 0) { num /= j; } } } if (num > 1) { fs.push_back(num); } int sz = (int) fs.size(); int cnt = 0; for (int mask = 0; mask < (1 << sz); mask++) { int sign = 1; int u = 1; for (int j = 0; j < sz; j++) { if (mask & (1 << j)) { sign *= -1; u *= fs[j]; } } cnt += sign * (bound / u); } ans *= cnt; } cout << ans << '\n'; } return0; }