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.
A cell is usable exactly when its row bit and column bit are equal: . So forget XOR for a second and think about equality constraints.
Look at one fixed path. If it moves right through and , then both and must equal . If it moves down through and , then both and must equal .
Any monotone path from to touches every row and every column , and the equality constraints along the path are connected. So all bits must become one common value. No path shape magic saves you here.
Therefore . Now define balance in , and similarly .
Use . This gives . The part sums directly; compute by sorting all values and using binary search plus prefix sums.
The grid sounds dynamic and path-dependent, but the actual trick is that the path is mostly a red herring. Once a path exists, it forces a whole prefix of rows and columns to agree.
After some flips, call the resulting strings still and for convenience. A cell has value iff
So a valid path is just a bunch of equality constraints between row variables and column variables .
Now fix a target and suppose some monotone path reaches it.
A monotone path from to visits every row and every column . These constraints are connected through the path, so they force
That is the whole damn problem. To reach , all bits in the two prefixes and must become the same bit.
The converse is also immediate: if all those prefix bits are equal, then every cell in the prefix rectangle is zero, so Yuri can take any monotone path.
So path choice does not matter anymore.
Let
In the combined prefixes there are
ones, and
zeros.
To make everything equal to , flip all ones. Cost: .
To make everything equal to , flip all zeros. Cost: .
Therefore
A direct sum is too slow, because can be .
Define prefix balance as
and similarly .
For the combined prefixes,
Also,
Using
we get
So the answer is
=\frac{\sum_{x=1}^{n}\sum_{y=1}^{n}(x+y)-\sum_{x=1}^{n}\sum_{y=1}^{n}|d_A[x]+d_B[y]|}{2}.$$ The first double sum is easy: $$\sum_{x=1}^{n}\sum_{y=1}^{n}(x+y)=n^2(n+1).$$ Now only this remains: $$T=\sum_{x=1}^{n}\sum_{y=1}^{n}|d_A[x]+d_B[y]|.$$ ## Computing the absolute-value sum Sort all values $d_B[y]$. Also build prefix sums over the sorted array. For a fixed value $u=d_A[x]$, we need $$\sum_y |u+d_B[y]|.$$ The expression $u+d_B[y]$ is negative when $$d_B[y]<-u.$$ So binary search the first position $k$ where $d_B[k]\ge -u$. For the left part, values are negative: $$\sum_{j<k}|u+d_B[j]|=\sum_{j<k}-(u+d_B[j])=-u\cdot k-\text{pref}[k].$$ For the right part, values are nonnegative: $$\sum_{j\ge k}|u+d_B[j]|=u\cdot(n-k)+(\text{pref}[n]-\text{pref}[k]).$$ Add both parts for every $d_A[x]$. Total complexity is $O(n\log n)$ per test case because of sorting and binary searches. The total $n$ over all tests is bounded, so this fits easily. Use `long long`; the answer can be around $n^3$, and `int` will explode like a bad contest hack.#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int T;
cin >> T;
while (T--) {
int n;
string a, b;
cin >> n >> a >> b;
vector<ll> da(n), db(n);
ll cur = 0;
for (int i = 0; i < n; i++) {
cur += (a[i] == '1' ? 1 : -1);
da[i] = cur;
}
cur = 0;
for (int i = 0; i < n; i++) {
cur += (b[i] == '1' ? 1 : -1);
db[i] = cur;
}
sort(db.begin(), db.end());
vector<ll> pref(n + 1, 0);
for (int i = 0; i < n; i++) pref[i + 1] = pref[i] + db[i];
ll absSum = 0;
for (ll u : da) {
int k = lower_bound(db.begin(), db.end(), -u) - db.begin();
ll left = -u * k - pref[k];
ll right = u * (n - k) + (pref[n] - pref[k]);
absSum += left + right;
}
ll totalXY = 1LL * n * n * (n + 1);
cout << (totalXY - absSum) / 2 << '\n';
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int T;
cin >> T;
while (T--) {
int n;
string a, b;
cin >> n >> a >> b;
vector<ll> da(n), db(n);
ll cur = 0;
for (int i = 0; i < n; i++) {
cur += (a[i] == '1' ? 1 : -1);
da[i] = cur;
}
cur = 0;
for (int i = 0; i < n; i++) {
cur += (b[i] == '1' ? 1 : -1);
db[i] = cur;
}
sort(db.begin(), db.end());
vector<ll> pref(n + 1, 0);
for (int i = 0; i < n; i++) pref[i + 1] = pref[i] + db[i];
ll absSum = 0;
for (ll u : da) {
int k = lower_bound(db.begin(), db.end(), -u) - db.begin();
ll left = -u * k - pref[k];
ll right = u * (n - k) + (pref[n] - pref[k]);
absSum += left + right;
}
ll totalXY = 1LL * n * n * (n + 1);
cout << (totalXY - absSum) / 2 << '\n';
}
return 0;
}