제출 #964454

#제출 시각아이디문제언어결과실행 시간메모리
964454TAhmed33늑대인간 (IOI18_werewolf)C++17
15 / 100
4037 ms131240 KiB
#include "werewolf.h" #include <bits/stdc++.h> using namespace std; const int MAXN = 4e5 + 25; const int B = 21; pair <int, int> edges[MAXN]; array <int, 4> queries[MAXN]; int ans[MAXN]; int n, m, q; struct DSU { int par[MAXN]; void init (int n) { for (int i = 1; i <= n; i++) par[i] = i; } int find (int x) { return par[x] == x ? x : par[x] = find(par[x]); } bool merge (int x, int y) { x = find(x), y = find(y); if (x == y) return 0; if (x > y) swap(x, y); par[x] = y; return 1; } } dd; struct tree { int p[MAXN]; vector <int> adj[MAXN]; int cnt; int in[MAXN], out[MAXN], tt, dp[MAXN]; int sparse[B][MAXN]; void init (int n) { cnt = n; } void link (int a, int b) { cnt++; p[a] = p[b] = cnt; adj[cnt].push_back(a); adj[cnt].push_back(b); } void dfs (int pos, bool c) { if (adj[pos].empty()) { dp[pos] = pos; return; } for (auto j : adj[pos]) { dfs(j, c); } if (!c) { if (dp[adj[pos][0]] > dp[adj[pos][1]]) swap(adj[pos][0], adj[pos][1]); dp[pos] = dp[adj[pos][0]]; } else { if (dp[adj[pos][0]] < dp[adj[pos][1]]) swap(adj[pos][0], adj[pos][1]); dp[pos] = dp[adj[pos][0]]; } } void dfs2 (int pos) { if (adj[pos].empty()) { in[pos] = out[pos] = ++tt; return; } for (auto j : adj[pos]) { dfs2(j); } in[pos] = in[adj[pos][0]]; out[pos] = out[adj[pos][1]]; } void build (bool c) { dfs(cnt, c); dfs2(cnt); for (int i = 1; i <= cnt; i++) { sparse[0][i] = p[i]; } for (int i = 1; i < B; i++) { for (int j = 1; j <= cnt; j++) { sparse[i][j] = sparse[i - 1][sparse[i - 1][j]]; } } } pair <int, int> get (int x, int y, bool c) { for (int i = B - 1; i >= 0; i--) { if (!sparse[i][x]) continue; if (!c) { if (dp[sparse[i][x]] >= y) x = sparse[i][x]; } else { if (dp[sparse[i][x]] <= y) x = sparse[i][x]; } } return {in[x], out[x]}; } } cur[2]; vector<int> check_validity (int N, vector <int> X, vector<int> Y, vector<int> S, vector<int> E, vector<int> L, vector<int> R) { n = N; m = (int)X.size(); q = S.size(); for (int i = 0; i < m; i++) { X[i]++; Y[i]++; } for (int i = 0; i < q; i++) { S[i]++; E[i]++; L[i]++; R[i]++; } for (int i = 1; i <= m; i++) { edges[i] = {X[i - 1], Y[i - 1]}; if (edges[i].first > edges[i].second) swap(edges[i].first, edges[i].second); } for (int i = 1; i <= q; i++) { queries[i] = {S[i - 1], E[i - 1], L[i - 1], R[i - 1]}; } sort(edges + 1, edges + m + 1, [] (pair <int, int> &a, pair <int, int> &b) { return a.first > b.first; }); dd.init(2 * n - 1); cur[0].init(n); for (int i = 1; i <= m; i++) { int a = dd.find(edges[i].first), b = dd.find(edges[i].second); if (a == b) continue; cur[0].link(a, b); dd.merge(a, b); dd.merge(a, cur[0].cnt); } sort(edges + 1, edges + m + 1, [] (pair <int, int> &a, pair <int, int> &b) { return a.second < b.second; }); dd.init(2 * n - 1); cur[1].init(n); for (int i = 1; i <= m; i++) { int a = dd.find(edges[i].first), b = dd.find(edges[i].second); if (a == b) continue; cur[1].link(a, b); dd.merge(a, b); dd.merge(a, cur[1].cnt); } cur[0].build(0); cur[1].build(1); for (int i = 1; i <= q; i++) { if (queries[i][0] < queries[i][2] || queries[i][1] > queries[i][3]) { ans[i] = 0; continue; } auto g = cur[0].get(queries[i][0], queries[i][2], 0); auto h = cur[1].get(queries[i][1], queries[i][3], 1); int flag = 0; for (int j = 1; j <= n; j++) { flag |= g.first <= cur[0].in[j] && cur[0].in[j] <= g.second && h.first <= cur[1].in[j] && cur[1].in[j] <= h.second; } ans[i] = flag; } vector <int> ret; for (int i = 1; i <= q; i++) ret.push_back(ans[i]); return ret; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...