Submission #81140

#TimeUsernameProblemLanguageResultExecution timeMemory
81140cki86201Werewolf (IOI18_werewolf)C++11
100 / 100
1047 ms425572 KiB
#include "werewolf.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <memory.h> #include <math.h> #include <assert.h> #include <stack> #include <queue> #include <map> #include <set> #include <string> #include <algorithm> #include <iostream> #include <functional> #include <unordered_set> using namespace std; typedef long long ll; typedef pair<int, int> pii; typedef pair<ll, ll> pll; #define Fi first #define Se second #define pb(x) push_back(x) #define szz(x) (int)x.size() #define rep(i,n) for(int i=0;i<n;i++) #define all(x) x.begin(),x.end() typedef tuple<int, int, int> t3; struct tree { vector <int> F[200020]; int lv[200020], rv[200020], cs = 0; int up[200020][18]; void addE(int x, int y) { // x <- y F[x].pb(y); } void dfs(int x) { lv[x] = ++cs; for(int e : F[x]) { up[e][0] = x; for(int i=1;i<18;i++) { up[e][i] = up[ up[e][i-1] ][i-1]; } dfs(e); } rv[x] = cs; } pii get_seg_g(int x, int l) { for(int i=17;i>=0;i--) { if(up[x][i] && up[x][i] >= l) x = up[x][i]; } return pii(lv[x], rv[x]); } pii get_seg_l(int x, int r) { for(int i=17;i>=0;i--) { if(up[x][i] && up[x][i] <= r) x = up[x][i]; } return pii(lv[x], rv[x]); } } T[2]; int pp[200020]; int Find(int x) { return pp[x] == x ? x : pp[x] = Find(pp[x]); } int val[200020]; vector <int> EE[200010]; int N; vector <t3> pquery[200020]; int TT[200020]; int cnt[200020]; void pre_query(int idx, int S, int E, int L, int R) { pii p1 = T[0].get_seg_l(E, R); pii p2 = T[1].get_seg_g(S, L); pquery[p1.Se].pb(t3(p2.Se, idx, 1)); pquery[p1.Se].pb(t3(p2.Fi-1, idx, -1)); pquery[p1.Fi-1].pb(t3(p2.Se, idx, -1)); pquery[p1.Fi-1].pb(t3(p2.Fi-1, idx, 1)); } std::vector<int> check_validity(int nn, 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 = nn; int M = szz(X); for(int i=0;i<M;i++) { int x = X[i] + 1, y = Y[i] + 1; EE[x].pb(y); EE[y].pb(x); } for(int i=1;i<=N;i++) pp[i] = i; for(int i=1;i<=N;i++) { for(int e : EE[i]) if(e < i) { int x = Find(i), y = Find(e); if(x == y) continue; pp[y] = x; T[0].addE(x, y); } } for(int i=1;i<=N;i++) pp[i] = i; for(int i=N;i;i--) { for(int e : EE[i]) if(e > i) { int x = Find(i), y = Find(e); if(x == y) continue; pp[y] = x; T[1].addE(x, y); } } T[0].dfs(N); T[1].dfs(1); for(int i=1;i<=N;i++) { val[T[0].lv[i]] = T[1].lv[i]; } int Q = szz(S); rep(i, Q) { ++S[i]; ++E[i]; ++L[i]; ++R[i]; pre_query(i, S[i], E[i], L[i], R[i]); } for(int i=1;i<=N;i++) { int x = val[i]; for(int j=x;j<200020;j+=(j&-j)) TT[j]++; for(t3 e : pquery[i]) { int y, idx, cc; tie(y, idx, cc) = e; int s = 0; for(int j=y;j;j-=(j&-j)) s += TT[j]; cnt[idx] += cc * s; } } vector <int> A(Q); rep(i, Q) { A[i] = cnt[i] > 0 ? 1 : 0; } return A; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...