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 forbidden pattern is exactly a checkerboard. It is not about adjacent rows/columns, and it is not normal numeric monotonicity.
For row , let be the set of black columns in that row. Two rows create a checkerboard iff both and are nonempty.
So the matrix is monotone iff every two row sets are nested by inclusion. For a pair, that is equivalent to .
Because always, it is enough to compare the sums over all row pairs: and .
Maintain . Adding cell increases the first sum by the number of rows with at least the new size of row , and increases the second sum by the old number of black cells in column .
Treat black as and white as . The bad configuration in the statement is exactly a checkerboard:
For each row , define as the set of columns where row is black.
Consider two rows . A checkerboard exists between them iff there is one column in and another column in . If both differences are nonempty, the two chosen columns form one of the two checkerboards depending on their order. If one difference is empty, then one set contains the other, and these two rows can never form a checkerboard.
So the whole matrix is monotone iff the row sets form a chain by inclusion:
Checking all pairs directly would be very dead, so we count a certificate instead.
For two rows define
This is always nonnegative, because an intersection cannot be larger than the smaller set. Also, exactly when the smaller row set is contained in the larger one. Therefore the matrix is monotone iff
Now split into two sums:
where
Maintain by columns. If column currently has black cells, adding a new black cell in that column creates exactly new shared-column contributions with previous black rows in that column. So
Maintain by row sizes. Suppose row currently has size , and after the update it becomes . For another row with size ,
So increases by the number of rows whose current size is at least . Let store the number of rows with at least black cells. Since row currently has only cells, it is not included in , which is perfect. Then after using it, increment because row now reaches that threshold.
For an update :
Then update:
The answer is YES iff . If , at least one row pair is not nested, so a checkerboard exists. No vibes, no sorting, no matrix storage. Just the invariant doing its job.
Correctness proof.
First, for any pair of rows , they violate monotonicity iff and are incomparable. If they are incomparable, pick and ; the two columns form a checkerboard. Conversely, any checkerboard gives one column in each of those two differences, so the sets are incomparable.
Second, for every pair , iff and are comparable. Since every , the total iff every pair has , iff every pair of rows is comparable, iff the matrix is monotone.
Third, the maintained value of is exact because each column independently contributes one to for every pair of rows black in that column. Adding a cell to a column with previous black cells creates exactly new such row pairs.
Fourth, the maintained value of is exact because only pairs involving the updated row can change. If its size changes from to , exactly the rows with size at least increase their pair minimum by , which is exactly before the update.
Thus after every query, is exactly , and printing YES iff is correct.
Edge cases. Empty rows are harmless because they are subsets of everything. The first black cell always keeps . The statement guarantees no cell is inserted twice, so column counts are enough; we never need a grid.
Complexity. Each query is . Each test case uses memory. Over all tests, the complexity is .
Research checked: the official Codeforces problem/editorial page https://codeforces.com/blog/entry/151515, accepted-submission status https://codeforces.com/problemset/status/2201/problem/F1, and Luogu writeups https://www.luogu.com/article/fbtt01bd and https://www.luogu.com.cn/article/sxr8azbm.
#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, q;
cin >> n >> q;
vector<int> row(n + 1, 0), col(n + 1, 0), ge(n + 2, 0);
ll diff = 0;
while (q--) {
int r, c;
cin >> r >> c;
int newRowSize = row[r] + 1;
diff += ge[newRowSize];
row[r] = newRowSize;
ge[newRowSize]++;
diff -= col[c];
col[c]++;
cout << (diff == 0 ? "YES\n" : "NO\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, q;
cin >> n >> q;
vector<int> row(n + 1, 0), col(n + 1, 0), ge(n + 2, 0);
ll diff = 0;
while (q--) {
int r, c;
cin >> r >> c;
int newRowSize = row[r] + 1;
diff += ge[newRowSize];
row[r] = newRowSize;
ge[newRowSize]++;
diff -= col[c];
col[c]++;
cout << (diff == 0 ? "YES\n" : "NO\n");
}
}
return 0;
}