Submission #296947

#TimeUsernameProblemLanguageResultExecution timeMemory
296947ChrisTWerewolf (IOI18_werewolf)C++17
100 / 100
1258 ms120188 KiB
#include <bits/stdc++.h> #include "werewolf.h" using namespace std; const int MN = 2e5 + 3; struct Query { int l,r,l2,r2,id; }; vector<int> check_validity (int n, vector<int> x, vector<int> y, vector<int> s, vector<int> e, vector<int> l, vector<int> r) { int m = (int)x.size(), qq = (int)s.size(), LOG = __lg(n) + 1; vector<vector<int>> aaa(n+1); array<vector<vector<int>>,2> adj; for (int j = 0; j < 2; j++) adj[j].resize(n+1); vector<int> ret(qq); for (int i = 0; i < m; i++) { aaa[++x[i]].push_back(++y[i]); aaa[y[i]].push_back(x[i]); } vector<int> p(n+1); iota(p.begin(),p.end(),0); //1 is for >=, 0 is for <= const auto find = [&] (int x, const auto &find_ref) -> int { return p[x] == x ? x : p[x] = find_ref(p[x],find_ref); }; const auto merge = [&] (int a, int b, bool lt) { if ((a = find(a,find)) == (b = find(b,find))) return; if ((a > b) ^ lt) swap(a,b); p[a] = b; adj[lt][b].push_back(a); }; for (int i = n; i >= 1; i--) for (int j : aaa[i]) if (j > i) merge(i,j,1); iota(p.begin(),p.end(),0); for (int i = 1; i <= n; i++) for (int j : aaa[i]) if (j < i) merge(i,j,0); int tt = 0; array<vector<int>,2> st,ed,which; array<vector<vector<int>>,2> jmp, par; for (int i = 0; i < 2; i++) st[i].resize(n+1), ed[i].resize(n+1), which[i].resize(n+1), jmp[i].resize(n+1,vector<int>(LOG)); const auto dfs = [&] (int cur, int p, int id, const auto &dfs_ref) -> void { which[id][st[id][cur] = ++tt] = cur; for (int i : adj[id][cur]) if (i != p) { jmp[id][i][0] = cur; for (int j = 1; j < LOG; j++) jmp[id][i][j] = jmp[id][jmp[id][i][j-1]][j-1]; dfs_ref(i,cur,id,dfs_ref); } ed[id][cur] = tt; }; dfs(1,-1,1,dfs); tt = 0; dfs(n,-1,0,dfs); const auto lift = [&] (int cur, int id, int x) { for (int j = LOG - 1; ~j; j--) if (jmp[id][cur][j] && (jmp[id][cur][j] == x || (id ^ (jmp[id][cur][j] < x)))) cur = jmp[id][cur][j]; return cur; }; vector<Query> queries(qq); for (int i = 0; i < qq; i++) { int golt = lift(++e[i],0,++r[i]), gogt = lift(++s[i],1,++l[i]); queries[i] = {st[0][golt],ed[0][golt],st[1][gogt],ed[1][gogt],i}; } vector<int> tree(n*2); auto update = [&tree,&n] (int i, int v) { for (tree[i += n - 1] = v; i > 1; i >>= 1) tree[i>>1] = max(tree[i],tree[i^1]); }; auto query = [&tree,&n] (int l, int r) { int ret = 0; for (l += n-1, r += n; l < r; l >>= 1, r >>= 1) { if (l&1) ret = max(ret,tree[l++]); if (r&1) ret = max(ret,tree[--r]); } return ret; }; sort(queries.begin(),queries.end(),[&](const Query &a, const Query &b){return a.r < b.r;}); int pp = 1; for (Query &q : queries) { while (pp <= q.r) { update(st[1][which[0][pp]],pp); ++pp; } ret[q.id] = query(q.l2,q.r2) >= q.l; } 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...