Submission #1218562

#TimeUsernameProblemLanguageResultExecution timeMemory
1218562turnejaWerewolf (IOI18_werewolf)C++20
100 / 100
1672 ms352932 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> using namespace std; using namespace __gnu_pbds; #define endl "\n" #define ll long long #define IOS ios_base::sync_with_stdio(false); cin.tie(nullptr); const int N = 1e6 + 5; const int INF = 1e9; const int K = 21; struct KRT { int parent[N]; int tin[N]; int up[K][N]; int val[N]; int sz[N]; int tour[N]; int L[N]; int R[N]; int timer = 0; int n; int e; int segtree[4 * N]; vector<int> adj[N]; KRT(int m) { e = m; n = m; for (int i = 0; i < n; i++) { parent[i] = i; val[i] = i; } } int dsu_find(int u) { if (parent[u] == u) { return u; } return parent[u] = dsu_find(parent[u]); } void add_edge(int u, int v, int wt) { u = dsu_find(u), v = dsu_find(v); if (u == v) { return; } val[e] = wt; parent[u] = e; parent[v] = e; parent[e] = e; adj[e].push_back(v); adj[e].push_back(u); adj[u].push_back(e); adj[v].push_back(e); e++; return; } void dfs(int u, int p) { tour[timer] = val[u]; tin[u] = timer++; up[0][u] = p; L[u] = INF; R[u] = -INF; for (int k = 1; k < K; k++) { up[k][u] = up[k - 1][up[k - 1][u]]; } for (int v : adj[u]) { if (v != p) { dfs(v, u); L[u] = min(L[u], L[v]); R[u] = max(R[u], R[v]); } } if (u < n) { L[u] = tin[u]; R[u] = tin[u]; } } int rmq(int l, int r, int lq, int rq, int node) { if (lq <= l && rq >= r) { return segtree[node]; } if (l > rq || r < lq) { return INF; } int mid = (l + r) / 2; return min(rmq(l, mid, lq, rq, 2 * node + 1), rmq(mid + 1, r, lq, rq, 2 * node + 2)); } void update(int l, int r, int ind, int val, int node) { if (l == r) { segtree[node] = val; return; } int mid = (l + r) / 2; if (ind >= l && ind <= mid) { update(l, mid, ind, val, 2 * node + 1); } else { update(mid + 1, r, ind, val, 2 * node + 2); } segtree[node] = min(segtree[2 * node + 1], segtree[2 * node + 2]); } void build(int l, int r, int node) { if (l > r) { return; } if (l == r) { segtree[node] = INF; return; } int mid = (l + r) / 2; build(l, mid, 2 * node + 1); build(mid + 1, r, 2 * node + 2); segtree[node] = min(segtree[2 * node + 1], segtree[2 * node + 2]); } }; std::vector<int> check_validity(int N, std::vector<int> X, std::vector<int> Y, std::vector<int> S, std::vector<int> E, std::vector<int> L, std::vector<int> R) { vector<int> ans; int n = N; KRT kmx(n); KRT kmn(n); vector<tuple<int, int, int>> edges; for (int i = 0; i < X.size(); i++) { edges.push_back(make_tuple(max(X[i], Y[i]), X[i], Y[i])); } sort(edges.begin(), edges.end()); for (auto [wt, u, v] : edges) { kmn.add_edge(u, v, wt); } edges.clear(); for (int i = 0; i < X.size(); i++) { edges.push_back(make_tuple(min(X[i], Y[i]), X[i], Y[i])); } sort(edges.begin(), edges.end()); reverse(edges.begin(), edges.end()); for (auto [wt, u, v] : edges) { kmx.add_edge(u, v, wt); } int root = kmx.dsu_find(0); kmx.dfs(root, root); root = kmn.dsu_find(0); kmn.dfs(root, root); int nmx = kmx.e, nmn = kmn.e; vector<tuple<int, int, int, int, int, int, int>> queries; int Q = S.size(); for (int i = 0; i < Q; i++) { int u = E[i]; for (int k = K - 1; k >= 0; k--) { if (kmn.val[kmn.up[k][u]] <= R[i]) { u = kmn.up[k][u]; } } int l = kmn.L[u], r = kmn.R[u]; queries.push_back(make_tuple(l, r, S[i], E[i], L[i], R[i], i)); } sort(queries.begin(), queries.end()); kmx.build(0, nmx - 1, 0); priority_queue<pair<int, int>> pq; for (int i = 0; i < n; i++) { kmx.update(0, nmx - 1, kmx.tin[i], kmn.tin[i], 0); pq.push({-kmn.tin[i], i}); } ans.resize(Q); for (auto [l, r, S, E, L, R, j] : queries) { while (pq.size() && -pq.top().first < l) { auto [_, i] = pq.top(); pq.pop(); kmx.update(0, nmx - 1, kmx.tin[i], INF, 0); } int u = S; for (int k = K - 1; k >= 0; k--) { if (kmx.val[kmx.up[k][u]] >= L) { u = kmx.up[k][u]; } } int f = kmx.rmq(0, nmx - 1, kmx.L[u], kmx.R[u], 0); if (f <= r) { ans[j] = 1; } else { ans[j] = 0; } } return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...