제출 #96832

#제출 시각아이디문제언어결과실행 시간메모리
96832youngyojun늑대인간 (IOI18_werewolf)C++11
100 / 100
1946 ms114752 KiB
#include "werewolf.h" #include <bits/stdc++.h> #define eb emplace_back #define sz(V) ((int)(V).size()) #define allv(V) ((V).begin()),((V).end()) #define sorv(V) sort(allv(V)) #define rb(x) ((x)&(-(x))) using namespace std; const int MAXN = 200055; const int MAXM = 400055; const int MAXQ = 200055; struct TRE { vector<int> G[MAXN]; int prt[18][MAXN], cnt[MAXN], dfo[MAXN]; int N, Rt; void add(int p, int v) { G[p].eb(v); } void dfs(int i, int &c) { cnt[i] = 1; dfo[i] = c++; for(int v : G[i]) { prt[0][v] = i; dfs(v, c); cnt[i] += cnt[v]; } } void run() { prt[0][Rt] = N; for(int i = 18; i--;) prt[i][N] = N; { int _ = 0; dfs(Rt, _); } for(int j = 1; j < 18; j++) for(int i = 0; i < N; i++) prt[j][i] = prt[j-1][prt[j-1][i]]; } } TA, TB; struct BIT { int d[MAXN]; void upd(int x) { for(x += 5; x < MAXN; x += rb(x)) d[x]++; } int get(int x) { int r = 0; for(x += 5; x; x -= rb(x)) r += d[x]; return r; } } bit; struct EVT { EVT(int idx, int x, int y, bool inv) : idx(idx), x(x), y(y), inv(inv) {} int idx, x, y; bool inv; bool operator < (const EVT &t) const { if(x != t.x) return x < t.x; return idx < t.idx; } }; vector<EVT> EV; vector<int> G[MAXN]; int ud[MAXN]; int A[MAXM], B[MAXM]; int CS[MAXQ], CE[MAXQ], L[MAXQ], R[MAXQ]; int Ans[MAXQ]; int N, M, Q; int uf(int i) { return i == ud[i] ? i : (ud[i] = uf(ud[i])); } void uf(int a, int b) { ud[uf(b)] = uf(a); } int getMx(int v, int c) { for(int i = 18, p; i--;) { p = TA.prt[i][v]; if(p <= c) v = p; } return v; } int getMn(int v, int c) { for(int i = 18, p; i--;) { p = TB.prt[i][v]; if(c <= p && p < N) v = p; } return v; } void getAns() { for(int i = 0, a, b; i < M; i++) { a = A[i]; b = B[i]; G[a].eb(b); G[b].eb(a); } TA.N = TB.N = N; TA.Rt = N-1; iota(ud, ud+N, 0); for(int i = 1; i < N; i++) for(int v : G[i]) { if(i < v) continue; v = uf(v); if(v != i) TA.add(i, v); uf(i, v); } iota(ud, ud+N, 0); for(int i = N; i--;) for(int v : G[i]) { if(v < i) continue; v = uf(v); if(v != i) TB.add(i, uf(v)); uf(i, v); } TA.run(); TB.run(); for(int i = 0; i < N; i++) EV.eb(-1, TA.dfo[i], TB.dfo[i], false); for(int i = 0, a, b; i < Q; i++) { a = getMx(CE[i], R[i]); b = getMn(CS[i], L[i]); EV.eb(i, TA.dfo[a]-1, TB.dfo[b]-1, true); EV.eb(i, TA.dfo[a]-1, TB.dfo[b]+TB.cnt[b]-1, false); a = TA.dfo[a]+TA.cnt[a]-1; EV.eb(i, a, TB.dfo[b]-1, false); EV.eb(i, a, TB.dfo[b]+TB.cnt[b]-1, true); } sorv(EV); for(auto &ev : EV) { if(ev.idx < 0) bit.upd(ev.y); else Ans[ev.idx] += bit.get(ev.y) * (ev.inv ? -1 : 1); } } 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) { ::N = N; ::M = sz(X); ::Q = sz(S); for(int i = 0; i < M; i++) { ::A[i] = X[i]; ::B[i] = Y[i]; } for(int i = 0; i < Q; i++) { ::CS[i] = S[i]; ::CE[i] = E[i]; ::L[i] = L[i]; ::R[i] = R[i]; } getAns(); vector<int> V; for(int i = 0; i < Q; i++) V.eb(!!Ans[i]); return V; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...