제출 #349128

#제출 시각아이디문제언어결과실행 시간메모리
349128two_sides늑대인간 (IOI18_werewolf)C++17
100 / 100
565 ms63948 KiB
#include <werewolf.h> #include <bits/stdc++.h> using namespace std; #define fi first #define se second using pii = pair <int, int>; struct query {int l, r, t, id;}; const int N = 200005; int par[2][N], val[2][N], siz[2][N]; vector <int> adj[2][N]; int ver[2][N]; int tin[2][N], tout[2][N], timer; int ans[N], BIT[N]; vector <query> que[N]; void updateBIT(int i) { for (; i < N; i += i & -i) BIT[i]++; } int queryBIT(int i) { int res = 0; for (; i > 0; i -= i & -i) res += BIT[i]; return res; } int getRoot(int id, int u) { if (!par[id][u]) return u ; return getRoot(id, par[id][u]); } void uniteSet(int id, int u, int v, int w) { u = getRoot(id, u); v = getRoot(id, v); if (u == v) return; if (siz[id][u] < siz[id][v]) swap(u, v); par[id][v] = u; val[id][v] = w; siz[id][u] += siz[id][v]; adj[id][u].push_back(v); } void DFS(int id, int u) { ver[id][tin[id][u] = ++timer] = u; for (int v : adj[id][u]) DFS(id, v); tout[id][u] = timer; } vector <int> check_validity(int n, vector <int> x, vector <int> y, vector <int> s, vector <int> e, vector <int> ll, vector <int> rr) { int m = x.size(), q = s.size(); vector <pii> edge(m); for (int i = 0; i < m; i++) edge[i] = {++x[i], ++y[i]}; for (int i = 1; i <= n; i++) siz[0][i] = siz[1][i] = 1; sort(edge.begin(), edge.end(), [](const pii &x, const pii &y) { return max(x.fi, x.se) < max(y.fi, y.se); }); for (auto e : edge) uniteSet(0, e.fi, e.se, max(e.fi, e.se)); for (int i = 1; i <= n; i++) if (!par[0][i]) DFS(0, i); sort(edge.begin(), edge.end(), [](const pii &x, const pii &y) { return min(x.fi, x.se) > min(y.fi, y.se); }); for (auto e : edge) uniteSet(1, e.fi, e.se, min(e.fi, e.se)); timer = 0; for (int i = 1; i <= n; i++) if (!par[1][i]) DFS(1, i); for (int i = 0; i < q; i++) { int u, v, l, r; u = s[i]; v = e[i]; l = ll[i]; r = rr[i]; u++; v++; l++; r++; swap(u, v); if (u > r || v < l) continue; while (par[0][u] && val[0][u] <= r) u = par[0][u]; int lo = 0, hi = adj[0][u].size() - 1; while (lo < hi) { int mi = (lo + hi + 1) / 2; if (val[0][adj[0][u][mi]] <= r) lo = mi; else hi = mi - 1; } int x1 = tin[0][u], x2; if (adj[0][u].empty() || val[0][adj[0][u][lo]] > r) x2 = tin[0][u]; else x2 = tout[0][adj[0][u][lo]]; while (par[1][v] && val[1][v] >= l) v = par[1][v]; lo = 0, hi = adj[1][v].size() - 1; while (lo < hi) { int mi = (lo + hi + 1) / 2; if (val[1][adj[1][v][mi]] >= l) lo = mi; else hi = mi - 1; } int y1 = tin[1][v], y2; if (adj[1][v].empty() || val[1][adj[1][v][lo]] < l) y2 = tin[1][v]; else y2 = tout[1][adj[1][v][lo]]; que[x1 - 1].push_back({y1, y2, -1, i}); que[x2].push_back({y1, y2, 1, i}); } vector <int> res(q); for (int i = 1; i <= n; i++) { updateBIT(tin[1][ver[0][i]]); for (auto ev : que[i]) ans[ev.id] += (queryBIT(ev.r) - queryBIT(ev.l - 1)) * ev.t; } for (int i = 0; i < q; i++) res[i] = ans[i] > 0; return res; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...