QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#465372 | #6872. Magma Cave | Fortitude | WA | 2631ms | 107772kb | C++23 | 5.9kb | 2024-07-06 20:26:18 | 2024-07-06 20:26:19 |
Judging History
answer
#include <bits/stdc++.h>
#define pb push_back
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()
#define f first
#define s second
using namespace std;
using ll = long long;
using pii = pair <int, int>;
const int N = 2e5 + 5;
int n, q, t[N], p[N], sz[N], d[N], T;
pii ed[N];
int get(int v) {
if (v == p[v])
return v;
return get(p[v]);
}
vector <pii> info;
bool uni(int u, int v) {
u = get(u), v = get(v);
if (u == v) {
return 0;
}
if (sz[u] > sz[v])
swap(u, v);
info.pb({u, v});
p[u] = v;
sz[v] += sz[u];
return 1;
}
void rollback() {
while (info.back().f != -1) {
auto [u, v] = info.back();
info.pop_back();
p[u] = u;
sz[v] -= sz[u];
}
info.pop_back();
}
void calc(int l, int r, vector <int> edges, bool rev) {
sort(all(edges));
if (rev)
reverse(all(edges));
/*cout << "The segment " << l << ' ' << r << '\n';
for (auto x : edges)
cout << x << ' ';
cout << '\n';*/
vector <int> dies;
info.pb({-1, -1});
for (auto w : edges) {
auto [x, y] = ed[w];
if (!uni(x, y))
dies.pb(w);
else
d[w] = r;
}
rollback();
if (l == r)
return;
int md = (l + r) / 2;
vector <int> e, L, R;
for (auto x : dies) {
if (t[x] <= md)
e.pb(x);
else
R.pb(x);
}
info.pb({-1, -1});
for (auto w : e) {
auto [x, y] = ed[w];
if (uni(x, y)) {
R.pb(w);
} else {
L.pb(w);
}
}
rollback();
info.pb({-1, -1});
for (int i = l; i <= md; ++i) {
if (t[i])
uni(ed[i].f, ed[i].s);
}
calc(md + 1, r, R, rev);
rollback();
calc(l, md, L, rev);
}
vector <int> vals[N * 4], f[N * 4];
void add(int l, int r, int x, int v = 1, int tl = 1, int tr = q) {
if (l > r || l > tr || r < tl)
return;
if (l <= tl && tr <= r) {
vals[v].pb(x);
return;
}
int tm = (tl + tr) / 2;
add(l, r, x, v * 2, tl, tm);
add(l, r, x, v * 2 + 1, tm + 1, tr);
}
void upd(int l, int r, int x, int y, int v = 1, int tl = 1, int tr = q) {
if (l > r || l > tr || r < tl)
return;
if (l <= tl && tr <= r) {
int i = lower_bound(all(vals[v]), x) - vals[v].begin();
for (; i < sz(f[v]); i |= i + 1)
f[v][i] += y;
return;
}
int tm = (tl + tr) / 2;
upd(l, r, x, y, v * 2, tl, tm);
upd(l, r, x, y, v * 2 + 1, tm + 1, tr);
}
int get(int w, int x, int v = 1, int tl = 1, int tr = q) {
int i = upper_bound(all(vals[v]), x) - vals[v].begin() - 1;
int res = 0;
for (; i >= 0; i &= i + 1, --i)
res += f[v][i];
if (tl == tr)
return res;
int tm = (tl + tr) / 2;
if (w <= tm)
return res + get(w, x, v * 2, tl, tm);
return res + get(w, x, v * 2 + 1, tm + 1, tr);
}
int tp[N], u[N], v[N], w[N], k[N], cur[N], L[N];
void solve() {
cin >> n >> q;
T = 0;
for (int i = 1; i <= n; ++i) {
p[i] = i;
sz[i] = 1;
}
for (int i = 1; i <= q; ++i)
t[i] = 0;
vector <int> edges;
for (int i = 1; i <= q; ++i) {
cin >> tp[i];
if (tp[i] == 1) {
cin >> u[i] >> v[i] >> w[i];
edges.pb(w[i]);
ed[w[i]] = {u[i], v[i]};
t[w[i]] = ++T;
}
else {
cin >> k[i] >> w[i];
cur[i] = T;
}
}
calc(1, T, edges, 0);
/*for (int i = 1; i <= q; ++i) {
if (t[i])
cout << i << ' ' << t[i] << ' ' << d[i] << '\n';
}*/
assert(info.empty());
int comp = n;
info.pb({-1, -1});
vector <int> ans(q + 1);
for (int i = 1; i <= q * 4; ++i)
vals[i].clear();
for (int i = 1; i <= q; ++i) {
if (t[i]) {
add(i, q, t[i]);
add(i, q, d[i] + 1);
}
}
for (int i = 1; i <= q * 4; ++i) {
sort(all(vals[i]));
vals[i].erase(unique(all(vals[i])), vals[i].end());
f[i].resize(sz(vals[i]), 0);
}
for (int i = 1; i <= q; ++i) {
if (tp[i] == 1) {
if (uni(u[i], v[i]))
comp--;
if (t[w[i]] <= d[w[i]]) {
upd(w[i], q, t[w[i]], 1);
upd(w[i], q, d[w[i]] + 1, -1);
}
} else {
if (comp != 1) {
ans[i] = 1;
continue;
}
L[i] = get(w[i], cur[i]);
}
}
rollback();
for (int i = 1; i <= q; ++i)
d[i] = 0;
for (int i = 1; i <= q * 4; ++i) {
vals[i].clear();
}
calc(1, T, edges, 1);
for (int i = 1; i <= q; ++i) {
if (t[i]) {
add(1, i, t[i]);
add(1, i, d[i] + 1);
}
}
for (int i = 1; i <= q * 4; ++i) {
sort(all(vals[i]));
vals[i].erase(unique(all(vals[i])), vals[i].end());
f[i].resize(sz(vals[i]), 0);
}
for (int i = 1; i <= q; ++i) {
if (tp[i] == 1) {
if (t[w[i]] <= d[w[i]]) {
upd(1, w[i], t[w[i]], 1);
upd(1, w[i], d[w[i]] + 1, -1);
}
}
if (tp[i] == 2) {
if (ans[i] || !t[w[i]] || t[w[i]] > cur[i]) {
cout << "NO\n";
continue;
}
int R = get(w[i], cur[i]);
R = n - 1 - R;
if (R <= k[i] && k[i] <= L[i]) {
cout << "YES\n";
}
else {
cout << "NO\n";
}
}
}
assert(info.empty());
}
int main() {
ios :: sync_with_stdio(false);
cin.tie(nullptr);
int TT;
cin >> TT;
while (TT--)
solve();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 2631ms
memory: 107772kb
input:
100 500 1999 1 112 419 318 1 419 208 1700 1 208 255 603 1 255 202 306 1 202 54 326 1 54 468 1506 1 468 23 856 1 23 90 758 1 90 271 1104 1 271 442 1900 1 442 441 19 1 441 378 1227 1 378 466 24 1 466 186 228 1 186 399 1387 1 399 288 297 1 288 144 1763 1 144 418 1896 1 418 217 673 1 217 281 1259 1 281 ...
output:
NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO ...
result:
wrong answer 5th lines differ - expected: 'YES', found: 'NO'