QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#163397 | #7105. Pixel Art | ucup-team228 | AC ✓ | 485ms | 31740kb | C++20 | 5.1kb | 2023-09-04 03:07:02 | 2023-09-04 04:31:29 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct DSU {
static const int N = 1e5 + 10;
int Parent[N], Rank[N], Size[N], cnt;
void init(int n) {
for (int i = 1; i <= n; i++) {
Parent[i] = i, Rank[i] = 0, Size[i] = 1;
}
cnt = n;
}
int find(int v) {
if (Parent[v] == v) return v;
else return Parent[v] = find(Parent[v]);
}
void unite(int u, int v) {
u = find(u), v = find(v);
if (u == v) return;
if (Rank[u] < Rank[v]) swap(u, v);
if (Rank[v] == Rank[u]) Rank[u]++;
Parent[v] = u, cnt--;
Size[u] += Size[v];
}
};
DSU dsu;
#define close my_close
const int N = 1e5 + 10;
int r1[N], c1[N], r2[N], c2[N];
bool dead[N];
vector<pair<int, int>> row[N];
unordered_map<int, set<pair<int, int>>> col;
vector<int> open[N], close[N];
ll cnt_black[N], cnt_comp[N];
void init(int n, int m, int k) {
for (int i = 0; i <= n + 1; i++) {
row[i].clear();
open[i].clear();
close[i].clear();
cnt_black[i] = 0;
cnt_comp[i] = 0;
}
col.clear();
for (int i = 1; i <= k; i++) {
dead[i] = false;
}
}
bool check(int i, int j) {
return max(c1[i], c1[j]) <= min(c2[i], c2[j]);
}
void solve(int n, int m, int k) {
for (int i = 1; i <= k; i++) {
if (r1[i] == r2[i]) {
row[r1[i]].emplace_back(c1[i], i);
}
}
for (int i = 1; i <= n; i++) {
sort(row[i].begin(), row[i].end());
for (int j = int(row[i].size()) - 1; j >= 1; j--) {
int x = row[i][j - 1].second;
int y = row[i][j].second;
if (c2[x] + 1 == c1[y]) {
dead[y] = true;
c2[x] = c2[y];
}
}
}
for (int i = 1; i <= k; i++) {
if (r1[i] < r2[i]) {
col[c1[i]].emplace(r2[i], i);
}
}
for (int i = 1; i <= k; i++) {
if (!dead[i]) {
open[r1[i]].push_back(i);
close[r2[i] + 1].push_back(i);
cnt_black[r1[i]] += c2[i] - c1[i] + 1;
cnt_black[r2[i] + 1] -= c2[i] - c1[i] + 1;
}
}
for (int i = 1; i <= n; i++) {
cnt_black[i] += cnt_black[i - 1];
}
for (int i = 1; i <= n; i++) {
cnt_black[i] += cnt_black[i - 1];
}
set<pair<int, int>> cur;
dsu.init(k);
int not_seen = k;
for (int r = 1; r <= n; r++) {
for (int i : open[r]) {
not_seen--;
vector<int> tmp;
while (true) {
auto it = cur.lower_bound({c1[i], 0});
if (it == cur.end() || !check(i, it->second)) {
break;
} else {
int j = it->second;
dsu.unite(i, j);
tmp.push_back(j);
cur.erase({c2[j], j});
}
}
for (int j : tmp) {
cur.insert({c2[j], j});
}
auto lef = col[c1[i] - 1].lower_bound({r1[i], 0});
if (lef != col[c1[i] - 1].end() && r1[lef->second] <= r1[i]) {
dsu.unite(i, lef->second);
}
auto rig = col[c2[i] + 1].lower_bound({r1[i], 0});
if (rig != col[c2[i] + 1].end() && r1[rig->second] <= r1[i]) {
dsu.unite(i, rig->second);
}
}
for (int i : close[r]) {
cur.erase({c2[i], i});
}
for (int i : open[r]) {
cur.insert({c2[i], i});
}
cnt_comp[r] = dsu.cnt - not_seen;
}
}
void stress() {
mt19937 rnd;
while (true) {
int n = rnd() % 100 + 1;
int m = rnd() % 100 + 1;
int k = rnd() % 100 + 1;
init(n, m, k);
vector<vector<bool>> tmp(n + 1, vector<bool>(m + 1, false));
for (int i = 1; i <= k; i++) {
while (true) {
r1[i] = rnd() % n + 1;
r2[i] = rnd() % n + 1;
c1[i] = rnd() % m + 1;
c2[i] = rnd() % m + 1;
if (r1[i] > r2[i]) swap(r1[i], r2[i]);
if (c1[i] > c2[i]) swap(c1[i], c2[i]);
if (rnd() % 2 == 0) {
r2[i] = r1[i];
} else {
c2[i] = c1[i];
}
}
}
solve(n, m, k);
cout << "OK" << endl;
}
exit(0);
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
#ifdef LOCAL
freopen("input.txt", "r", stdin);
#endif
// stress();
int t;
cin >> t;
while (t--) {
int n, m, k;
cin >> n >> m >> k;
init(n, m, k);
for (int i = 1; i <= k; i++) {
cin >> r1[i] >> c1[i] >> r2[i] >> c2[i];
}
solve(n, m, k);
for (int i = 1; i <= n; i++) {
cout << cnt_black[i] << " " << cnt_comp[i] << "\n";
}
}
#ifdef LOCAL
cout << "\nTime elapsed: " << double(clock()) / CLOCKS_PER_SEC << " s.\n";
#endif
}
这程序好像有点Bug,我给组数据试试?
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 3ms
memory: 11988kb
input:
3 2 5 2 1 1 1 2 2 3 2 5 2 5 2 1 1 1 3 2 3 2 5 3 3 3 1 1 1 2 3 1 3 2 1 3 2 3
output:
2 1 5 2 3 1 6 1 3 1 4 1 6 2
result:
ok 7 lines
Test #2:
score: 0
Accepted
time: 485ms
memory: 31740kb
input:
2130 2 5 2 1 1 1 2 2 3 2 5 2 5 2 1 1 1 3 2 3 2 5 3 3 3 1 1 1 2 3 1 3 2 1 3 2 3 3 100 51 1 2 2 2 1 4 2 4 1 6 2 6 1 8 2 8 1 10 2 10 1 12 2 12 1 14 2 14 1 16 2 16 1 18 2 18 1 20 2 20 1 22 2 22 1 24 2 24 1 26 2 26 1 28 2 28 1 30 2 30 1 32 2 32 1 34 2 34 1 36 2 36 1 38 2 38 1 40 2 40 1 42 2 42 1 44 2 44 ...
output:
2 1 5 2 3 1 6 1 3 1 4 1 6 2 50 50 100 50 200 1 50 50 150 1 200 1 2 1 4 1 6 1 8 1 10 1 12 1 14 1 16 1 18 1 20 1 22 1 24 1 26 1 28 1 30 1 32 1 34 1 36 1 38 1 40 1 42 1 44 1 46 1 48 1 50 1 52 1 54 1 56 1 58 1 60 1 62 1 64 1 66 1 68 1 70 1 72 1 74 1 76 1 78 1 80 1 82 1 84 1 86 1 88 1 90 1 92 1 94 1 96 1...
result:
ok 355756 lines
Extra Test:
score: 0
Extra Test Passed