Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
The deletion process is stack cancellation. Give 1 value and 0 value ; the surviving zeros are exactly the moments where the prefix balance reaches a new negative low.
If the prefix balances are , , and , then . The simultaneous deletion wording is bait; the normal form is the same stack result.
For the reversed string, its prefix balances are . So if , then .
Therefore the whole condition collapses to . Count walks of length whose final height equals their minimum plus their maximum.
Fix exact minimum and maximum , use reflection in the strip between and , then sum all strips of the same width. After collecting binomial coefficients, the shortcut is , where .
The operation 10 -> empty is just stack cancellation. Scan left to right. If the next character is 0 and the top unmatched character is 1, they cancel; otherwise the character stays. The final string must be some zeros followed by some ones, because any surviving 1 before a surviving 0 would still contain 10.
Set for 1, for 0, and let
Let
Every time the balance reaches a new negative low, that 0 cannot be matched with any earlier unmatched 1, so it survives. Therefore the number of surviving zeros in is . Deletions remove equal numbers of zeros and ones, so the number of surviving ones is . Hence
For , its prefix sums are exactly in some order. Its minimum is , so
Now compare the two normal forms. We need
and both equations say the same thing:
So the problem is no longer about strings. It is: count length- walks with steps such that the final height equals minimum height plus maximum height.
Fix the exact minimum and exact maximum . We must have , and the final height is forced to be .
Use a grid path view: 0 is a right step, 1 is an up step, and the balance is . If the final balance is , then the endpoint is
Invalid parity just means zero paths.
Define as the number of paths from to that stay strictly inside the strip
The reflection principle gives
where out-of-range binomial coefficients are treated as .
To force exact minimum and exact maximum , use inclusion-exclusion. Staying between and inclusively is the same as staying strictly between and , so the exact count is
Doing this separately for every pair would be too slow. The useful compression is to group by width .
For a fixed width , summing one strip term over all valid makes the first binomial sweep through whole consecutive blocks. Across all reflected copies, those blocks contribute . The reflected subtraction contributes repeated terms of the form
The other three inclusion-exclusion terms are the same thing shifted by one boundary. After collecting the coefficient of every , the divisor sum appears.
Why? A term hits when
or, for the shifted terms,
Each such width contributes weight . Therefore define
The final formula is
That is the whole count. The scary palindrome thing got downgraded into prefix min/max, then into a divisor-weighted binomial sum. Very rude problem, but fair.
Precompute up to , because can be . For every possible divisor , add to all numbers where is odd:
for (int x = d; x <= N + 1; x += 2 * d) g[x] += d;
Then precompute factorials, inverse factorials, and powers of two modulo . Each test case is a direct evaluation of the formula.
Total complexity is , with , easily fine for the easy version.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MOD = 998244353;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
ll modpow(ll a, ll e) {
ll r = 1;
while (e) {
if (e & 1) r = r * a % MOD;
a = a * a % MOD;
e >>= 1;
}
return r;
}
int main() {
setIO();
int T;
cin >> T;
vector<int> ns(T);
int N = 0;
for (int &n : ns) {
cin >> n;
N = max(N, n);
}
vector<int> g(N + 2);
for (int d = 1; d <= N + 1; d++) {
for (int x = d; x <= N + 1; x += 2 * d) {
g[x] += d;
if (g[x] >= MOD) g[x] -= MOD;
}
}
vector<int> fac(N + 1), ifac(N + 1), pow2(N + 1);
fac[0] = ifac[0] = pow2[0] = 1;
for (int i = 1; i <= N; i++) {
fac[i] = (ll)fac[i - 1] * i % MOD;
pow2[i] = pow2[i - 1] * 2LL % MOD;
}
ifac[N] = modpow(fac[N], MOD - 2);
for (int i = N; i >= 1; i--) {
ifac[i - 1] = (ll)ifac[i] * i % MOD;
}
for (int n : ns) {
ll ans = (n & 1) ? pow2[n] : MOD - pow2[n];
for (int i = 0; i <= n; i++) {
ll comb = (ll)fac[n] * ifac[i] % MOD * ifac[n - i] % MOD;
int a = abs(n - 2 * i - 1);
int b = abs(n - 2 * i);
int diff = g[a] - g[b];
if (diff < 0) diff += MOD;
ans = (ans + 2LL * comb % MOD * diff) % MOD;
}
cout << ans << '\n';
}
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MOD = 998244353;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
ll modpow(ll a, ll e) {
ll r = 1;
while (e) {
if (e & 1) r = r * a % MOD;
a = a * a % MOD;
e >>= 1;
}
return r;
}
int main() {
setIO();
int T;
cin >> T;
vector<int> ns(T);
int N = 0;
for (int &n : ns) {
cin >> n;
N = max(N, n);
}
vector<int> g(N + 2);
for (int d = 1; d <= N + 1; d++) {
for (int x = d; x <= N + 1; x += 2 * d) {
g[x] += d;
if (g[x] >= MOD) g[x] -= MOD;
}
}
vector<int> fac(N + 1), ifac(N + 1), pow2(N + 1);
fac[0] = ifac[0] = pow2[0] = 1;
for (int i = 1; i <= N; i++) {
fac[i] = (ll)fac[i - 1] * i % MOD;
pow2[i] = pow2[i - 1] * 2LL % MOD;
}
ifac[N] = modpow(fac[N], MOD - 2);
for (int i = N; i >= 1; i--) {
ifac[i - 1] = (ll)ifac[i] * i % MOD;
}
for (int n : ns) {
ll ans = (n & 1) ? pow2[n] : MOD - pow2[n];
for (int i = 0; i <= n; i++) {
ll comb = (ll)fac[n] * ifac[i] % MOD * ifac[n - i] % MOD;
int a = abs(n - 2 * i - 1);
int b = abs(n - 2 * i);
int diff = g[a] - g[b];
if (diff < 0) diff += MOD;
ans = (ans + 2LL * comb % MOD * diff) % MOD;
}
cout << ans << '\n';
}
}