Submission #377231

#TimeUsernameProblemLanguageResultExecution timeMemory
377231CaroLindaWerewolf (IOI18_werewolf)C++14
100 / 100
2308 ms156044 KiB
#include "werewolf.h" #include <bits/stdc++.h> #define sz(x) (int)(x.size()) #define all(x) x.begin(),x.end() #define ll long long const int MAXN = 2e5+10 ; const int LOG = 20 ; using namespace std ; struct Tree { vector<int> tree[MAXN] ; int currTime ; int tin[MAXN] , tout[MAXN] , rep[MAXN] ; int dp[LOG][MAXN] ; int dsu[MAXN] , label[MAXN] ; Tree() { for(int i = 0 ; i < MAXN ; i++ ) dsu[i] =rep[i] = i ; memset(dp, -1, sizeof dp ); } int find(int x) { if( x == dsu[x] ) return x ; return dsu[x] = find(dsu[x] ) ; } void join(int x, int y ) { x = find(x) ; y = find(y) ; if( x == y ) return ; if(rand() % 2 ) swap(x,y) ; dsu[x] = y ; if(label[ rep[x] ] > label[ rep[y] ] ) { tree[ rep[x] ].push_back(rep[y] ) ; rep[y] = rep[x] ; } else tree[ rep[y] ].push_back(rep[x] ) ; } void dfs(int x) { for(int i = 1 ; i < LOG && dp[i-1][x] != -1 ; i++ ) dp[i][x] = dp[i-1][ dp[i-1][x] ] ; tin[x] = tout[x] = currTime++ ; for(auto child : tree[x] ) { dp[0][child] = x ; dfs(child) ; tout[x] = tout[child] ; } } } leftToRight, rightToLeft ; struct SegmentTree { vector< int > tree[MAXN*4] ; int m(int l, int r ) { return (l+r)>>1 ; } void upd(int pos, int l, int r, int idx , int k ) { tree[pos].push_back(k) ; if( l == r ) return ; if(idx <= m(l,r) ) upd(pos<<1 , l, m(l,r) , idx , k ) ; else upd(pos<<1|1 , m(l,r)+1 , r , idx , k ) ; } void qry(int pos, int l, int r, int beg, int en , pair<int,int> interval , bool &ok ) { if( l > en || r < beg ) return ; if( !(l >= beg && r <= en ) ) { qry(pos<<1 , l , m(l,r) , beg, en, interval, ok ) ; qry(pos<<1|1 , m(l,r)+1, r, beg, en, interval, ok ) ; return ; } int low = 0 , high = sz(tree[pos])-1 , best = interval.second+1 , mid ; while(low <= high ) { mid = (low+high)>>1 ; if(tree[pos][mid] >= interval.first ) { best = tree[pos][mid] ; high = mid-1 ; } else low = mid+1 ; } ok |= ( best <= interval.second ) ; } } seg ; 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 = sz(X) ; vector< vector<int> > biggerThanMe(N, vector<int>() ) ; vector< vector<int> > smallerThanMe(N, vector<int>() ) ; for(int i = 0 ; i < M ; i++ ) { if(X[i] > Y[i] ) swap(X[i], Y[i]) ; biggerThanMe[X[i]].push_back(Y[i]) ; smallerThanMe[Y[i]].push_back(X[i]) ; } for(int i = 0 ; i < N ; i++ ) { leftToRight.label[i] = i ; rightToLeft.label[i] = -i ; } for(int i = 0 ; i < N ; i++ ) for(auto neighbor : smallerThanMe[i] ) leftToRight.join(neighbor, i) ; leftToRight.dfs(N-1) ; for(int i = N-1 ; i >= 0 ; i-- ) for(auto neighbor : biggerThanMe[i] ) rightToLeft.join(neighbor, i) ; rightToLeft.dfs(0) ; vector<int> inRightToLeft(N) ; for(int i = 0 ; i < N ; i++ ) inRightToLeft[ leftToRight.tin[i] ] = rightToLeft.tin[i] ; for(int i= 0 ; i < N ; i++ ) seg.upd(1,0,N-1, inRightToLeft[i], i ) ; vector<int> ans ; for(int i = 0 ; i < sz(S) ; i++ ) { if( !( S[i] >= L[i] && E[i] <= R[i]) ) { ans.push_back(0) ; continue ; } int bestAncestor = S[i] ; for(int j = LOG-1 ; j >= 0 ; j-- ) if( rightToLeft.dp[j][bestAncestor] >= L[i] ) bestAncestor = rightToLeft.dp[j][bestAncestor] ; pair<int,int> intervalHuman = make_pair( rightToLeft.tin[bestAncestor], rightToLeft.tout[bestAncestor] ) ; bestAncestor = E[i] ; for(int j = LOG-1 ; j >= 0 ; j-- ) { int anc = leftToRight.dp[j][bestAncestor] ; if(anc != -1 && anc <= R[i] ) bestAncestor=anc; } pair<int,int> intervalWolf = make_pair( leftToRight.tin[bestAncestor], leftToRight.tout[bestAncestor] ) ; bool ok = false ; seg.qry(1, 0, N-1, intervalHuman.first, intervalHuman.second, intervalWolf, ok ) ; ans.push_back( ok ? 1 : 0 ) ; } 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...