Submission #434326

#TimeUsernameProblemLanguageResultExecution timeMemory
434326frodakcinWerewolf (IOI18_werewolf)C++11
100 / 100
762 ms78332 KiB
#include "werewolf.h" #include <cassert> #include <algorithm> #include <functional> #include <numeric> template<typename T> bool ckmax(T& a, const T& b) {return b>a?a=b,1:0;} template<typename T> bool ckmin(T& a, const T& b) {return b<a?a=b,1:0;} const int MN = 2e5+10; const int MQ = 2e5+10; struct DSU { int S; std::vector<int> p; DSU(int _S): S(_S), p(_S, -1) {} int find(int n) {return p[n]==-1 ? n : p[n] = find(p[n]);} bool merge(int a, int b) // b into a { a=find(a), b=find(b); if(a==b) return 0; p[b]=a; // no rank return 1; } }; struct ST { public: int S; std::vector<int> v; ST(int _S=0): S(_S), v(4*_S, -1) {} void upd(int n, int l, int r, int q, int val) { if(r-l>1) { int m=l+(r-l)/2; if(q < m) upd(n<<1, l, m, q, val); else upd(n<<1|1, m, r, q, val); v[n]=std::max(v[n<<1], v[n<<1|1]); } else v[n]=val; } void upd(int q, int val) {upd(1, 0, S, q, val);} int qry(int n, int l, int r, int ql, int qr) { if(ql <= l&&r <= qr) return v[n]; if(r-l>1) { int m=l+(r-l)/2, f=-1; if(ql < m) ckmax(f, qry(n<<1, l, m, ql, qr)); if(m < qr) ckmax(f, qry(n<<1|1, m, r, ql, qr)); return f; } assert(0); return -1; } int qry(int ql, int qr) {return qry(1, 0, S, ql, qr);} }; int N, M, Q; std::vector<int> a[MN], t[2][MN], ans, todo[MN]; int pre[2][MN], post[2][MN], ord[2][MN], ctr[2]; template<int T> void dfs(int n, int p=-1) { ord[T][ctr[T]]=n; pre[T][n]=ctr[T]++; for(int x:t[T][n]) if(x!=p) dfs<T>(x, n); post[T][n]=ctr[T]; } 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=X.size(); Q=S.size(); ans.assign(Q, -1); for(int i=0;i<M;++i) { a[X[i]].push_back(Y[i]); a[Y[i]].push_back(X[i]); } std::vector<int> ss(Q, -1), es(Q, -1); // start/end subtrees //human tree { std::vector<int> ord(Q); std::iota(ord.begin(), ord.end(), 0); std::sort(ord.begin(), ord.end(), [&](int u, int v){return L[u]>L[v];}); DSU dsu(N); for(int i=N-1, j=0;i>=0;--i) { for(int x:a[i]) { int y=dsu.find(x); if(i < x && dsu.merge(i, y)) t[0][i].push_back(y), t[0][y].push_back(i); } for(;j < Q && L[ord[j]]==i;++j) ss[ord[j]]=dsu.find(S[ord[j]]); } } //werewolf tree { std::vector<int> ord(Q); std::iota(ord.begin(), ord.end(), 0); std::sort(ord.begin(), ord.end(), [&](int u, int v){return R[u]<R[v];}); DSU dsu(N); for(int i=0, j=0;i<N;++i) { for(int x:a[i]) { int y=dsu.find(x); if(x < i && dsu.merge(i, y)) t[1][i].push_back(y), t[1][y].push_back(i); } for(;j < Q && R[ord[j]]==i;++j) es[ord[j]]=dsu.find(E[ord[j]]); } } dfs<0>(0); dfs<1>(N-1); for(int i=0;i<Q;++i) todo[post[1][es[i]]].push_back(i); ST segtree(N); for(int i=0;i<N;++i) { segtree.upd(pre[0][ord[1][i]], i); // add ord[1][i] for(int x:todo[i+1]) { ans[x] = segtree.qry(pre[0][ss[x]], post[0][ss[x]]) >= pre[1][es[x]]; //printf("\t%d: %d\n", x, segtree.qry(pre[0][ss[x]], post[0][ss[x]])); } } 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...