Submission #132303

#TimeUsernameProblemLanguageResultExecution timeMemory
132303figter001Werewolf (IOI18_werewolf)C++17
0 / 100
4018 ms98908 KiB
#include "werewolf.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int nax = 2e5+50; int dsu[nax]; int sz_sg[nax],p_sg[nax][20],fr_sg[nax],to_sg[nax],val_sg[nax],nxt_sg[nax],seg_sg[nax],d_sg[nax]; int sz_bg[nax],p_bg[nax][20],fr_bg[nax],to_bg[nax],val_bg[nax],nxt_bg[nax],seg_bg[nax],d_bg[nax]; int n,m,T = 1; vector<int> sg[nax],bg[nax]; // DSU int find(int u){ return u == dsu[u] ? u : dsu[u] = find(dsu[u]); } // HLD SMALL Graph void dfs_sz_sg(int u,int p){ sz_sg[u] = 1; for(auto &v: sg[u]) { if(v == p)continue; d_sg[v] = d_sg[u] + 1; p_sg[v][0] = u; for(int i=1;i<20;i++)p_sg[v][i] = p_sg[p_sg[v][i-1]][i-1]; dfs_sz_sg(v,u); sz_sg[u] += sz_sg[v]; if(sz_sg[v] > sz_sg[sg[u][0]]) { swap(v, sg[u][0]); } } } void dfs_hld_sg(int u,int par) { fr_sg[u] = T++; val_sg[fr_sg[u]] = u; for(auto v: sg[u]) { if(v == par)continue; nxt_sg[v] = (v == sg[u][0] ? nxt_sg[u] : v); dfs_hld_sg(v,u); } to_sg[u] = T; } void hld_sg(){ T=1; dfs_sz_sg(1,0); dfs_hld_sg(1,0); } // HLD BIG Graph void dfs_sz_bg(int u,int p){ sz_bg[u] = 1; for(auto &v: bg[u]) { if(v == p)continue; d_bg[v] = d_bg[u] + 1; p_bg[v][0] = u; for(int i=1;i<20;i++)p_bg[v][i] = p_bg[p_bg[v][i-1]][i-1]; dfs_sz_bg(v,u); sz_bg[u] += sz_bg[v]; if(sz_bg[v] > sz_bg[bg[u][0]]) { swap(v, bg[u][0]); } } } void dfs_hld_bg(int u,int par) { fr_bg[u] = T++; val_bg[fr_bg[u]] = u; for(auto v: bg[u]) { if(v == par)continue; nxt_bg[v] = (v == bg[u][0] ? nxt_bg[u] : v); dfs_hld_bg(v,u); } to_bg[u] = T; } void hld_bg(){ T=1; dfs_sz_bg(n,0); dfs_hld_bg(n,0); } // SMALL Tree Segment tree void build_sg(int n,int s,int e){ if(s == e){ seg_sg[n] = val_sg[s]; return; } build_sg(n*2,s,(s+e)/2); build_sg(n*2+1,(s+e)/2+1,e); seg_sg[n] = max( seg_sg[n*2] , seg_sg[n*2+1] ); } int get_sg(int n,int s,int e,int l,int r){ if(s > r || e < l)return 0; if(s >= l && e <= r)return seg_sg[n]; return max( get_sg(n*2,s,(s+e)/2,l,r) , get_sg(n*2+1,(s+e)/2+1,e,l,r) ); } // BIG Tree Segment tree void build_bg(int n,int s,int e){ if(s == e){ seg_bg[n] = val_bg[s]; return; } build_bg(n*2,s,(s+e)/2); build_bg(n*2+1,(s+e)/2+1,e); seg_bg[n] = min( seg_bg[n*2] , seg_bg[n*2+1] ); } int get_bg(int n,int s,int e,int l,int r){ if(s > r || e < l)return 1e9; if(s >= l && e <= r)return seg_bg[n]; return min( get_bg(n*2,s,(s+e)/2,l,r) , get_bg(n*2+1,(s+e)/2+1,e,l,r) ); } // SMALL TREE LCA int kth_sg(int u,int dif){ for(int k = 19;k>=0;k--){ if( (dif >> k) & 1 ){ u = p_sg[u][k]; } } return u; } int lca_sg(int u,int v){ if(d_sg[u] < d_sg[v])swap(u,v); int dif = d_sg[u] - d_sg[v]; assert(dif >= 0); u = kth_sg(u,dif); if(u == v)return u; for(int k=19;k>=0;k--){ if(p_sg[u][k] != p_sg[v][k]){ u = p_sg[u][k]; v = p_sg[v][k]; } } assert(u!=v); return p_sg[u][0]; } // BIG Tree LCA int kth_bg(int u,int dif){ for(int k = 19;k>=0;k--){ if( (dif >> k) & 1 ){ u = p_bg[u][k]; } } return u; } int lca_bg(int u,int v){ if(d_bg[u] < d_bg[v])swap(u,v); int dif = d_bg[u] - d_bg[v]; assert(dif >= 0); u = kth_bg(u,dif); if(u == v)return u; for(int k=19;k>=0;k--){ if(p_bg[u][k] != p_bg[v][k]){ u = p_bg[u][k]; v = p_bg[v][k]; } } assert(u!=v); return p_bg[u][0]; } // Answring Queries int find_smallest(int u,int v,int l,int r){ int small = -1; int w = lca_bg(u,v); assert(w); bool done = 0; int tmp,lo,hi,md; for(int x = u;!done;x=p_bg[nxt_bg[x]][0]){ if(d_bg[nxt_bg[x]] <= d_bg[w]){ tmp = get_bg(1,1,n,fr_bg[w],fr_bg[x]); lo = fr_bg[w];hi = fr_bg[x]; done = 1; }else{ tmp = get_bg(1,1,n,fr_bg[nxt_bg[x]],fr_bg[x]); lo = fr_bg[nxt_bg[x]];hi = fr_bg[x]; } if(tmp < l){ int lim = hi; small = lo; while(lo <= hi){ md = (lo + hi)/2; int cur = get_bg(1,1,n,md,lim); if(cur >= l){ small = md; hi = md-1; }else lo = md+1; } assert(small); return small; } } done = 0; vector<pair<int,pair<int,int>>> ranges; for(int x = v;!done;x=p_bg[nxt_bg[x]][0]){ if(d_bg[nxt_bg[x]] <= d_bg[w]){ tmp = get_bg(1,1,n,fr_bg[w],fr_bg[x]); lo = fr_bg[w];hi = fr_bg[x]; done = 1; }else{ tmp = get_bg(1,1,n,fr_bg[nxt_bg[x]],fr_bg[x]); lo = fr_bg[nxt_bg[x]];hi = fr_bg[x]; } ranges.push_back({tmp,{lo,hi}}); } reverse(ranges.begin(),ranges.end()); for(auto cur : ranges){ lo = cur.second.first; hi = cur.second.second; int lim = lo; int val = cur.first; if(val < l){ small = lo; while(lo <= hi){ md = (lo + hi)/2; int cur = get_bg(1,1,n,lim,md); if(cur >= l){ small = md; lo = md+1; }else hi = md-1; } assert(small); return small; } } return 0; } int find_largest(int u,int v,int l,int r){ int w = lca_sg(u,v); int tmp; assert(w); bool done = 0; for(int x = u;!done;x=p_sg[nxt_sg[x]][0]){ if(d_sg[nxt_sg[x]] <= d_sg[w]){ tmp = get_sg(1,1,n,fr_sg[w],fr_sg[x]); done = 1; }else{ tmp = get_sg(1,1,n,fr_sg[nxt_sg[x]],fr_sg[x]); } if(tmp > r)return 0; } done = 0; for(int x = v;!done;x=p_sg[nxt_sg[x]][0]){ if(d_sg[nxt_sg[x]] <= d_sg[w]){ tmp = get_sg(1,1,n,fr_sg[w],fr_sg[x]); done = 1; }else{ tmp = get_sg(1,1,n,fr_sg[nxt_sg[x]],fr_sg[x]); } if(tmp > r)return 0; } return 1; } int solve(int fr,int to,int l,int r){ fr = find_smallest(fr,to,l,r); if(fr == 0)return 1; fr = get_bg(1,1,n,fr,fr); if(fr > r || fr < l)return 0; return find_largest(fr,to,l,r); } 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 = x.size(); int Q = S.size(); vector<vector<int>> tmp(n+1); for(int i=0;i<m;i++){ int u = x[i]; int v = y[i]; u++;v++; tmp[u].push_back(v); tmp[v].push_back(u); } for(int i=1;i<=n;i++){ sort(tmp[i].begin(),tmp[i].end()); dsu[i] = i; } for(int u=1;u<=n;u++){ for(int v : tmp[u]){ if(find(v) == find(u) || u > v)continue; sg[u].push_back(v); sg[v].push_back(u); dsu[find(v)] = find(u); } } for(int i=1;i<=n;i++){ reverse(tmp[i].begin(),tmp[i].end()); dsu[i] = i; } for(int u=n;u>=1;u--){ for(int v : tmp[u]){ if(find(v) == find(u) || u < v)continue; bg[u].push_back(v); bg[v].push_back(u); dsu[find(v)] = find(u); } } for(int i=1;i<=n;i++){ nxt_sg[i] = 1; nxt_bg[i] = n; } hld_sg(); hld_bg(); build_sg(1,1,n); build_bg(1,1,n); vector<int> A(Q,0); for (int i = 0; i < Q; ++i) { S[i]++;E[i]++;L[i]++;R[i]++; A[i] = solve(S[i],E[i],L[i],R[i]); } 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...