Submission #381188

#TimeUsernameProblemLanguageResultExecution timeMemory
381188MatheusLealVWerewolf (IOI18_werewolf)C++17
100 / 100
1252 ms196392 KiB
#include "werewolf.h" #include <bits/stdc++.h> #define f first #define s second #define pb push_back #define mp make_pair #define all(x) begin(x), end(x) #define sz(x) (int)(x).size() #define rep(i, a, b) for (int i = (a); i < (b); ++i) using namespace std; #define N 500050 int n; int bit[N]; void upd(int x, int v){ x+=5; assert(x>0); for(int i = x; i < N; i += (i&-i)) bit[i] += v; } int query(int x){ x+=5; assert(x>0); int sum = 0; for(int i = x; i > 0; i -=(i&-i)) sum += bit[i]; return sum; } struct kruskal_tree{ vector<int>grafo[N]; int pai[N], nivel[N], anc[N][20],cnt, v[N]; int ini[N], fim[N], tempo; void init(){ for(int i=0;i< N;i++)pai[i]=i,nivel[i]=v[i]=0; tempo =0;cnt=n; } int find(int x){ if(x==pai[x])return x; return pai[x]=find(pai[x]); } void join(int a, int b, int cost){ a=find(a);b=find(b); if(a==b) return; ++cnt; pai[cnt]=cnt; grafo[cnt].pb(a); grafo[cnt].pb(b); pai[a]=cnt;pai[b]=cnt; v[cnt] = cost; } void dfs(int x, int p){ ini[x]=++tempo; nivel[x]=nivel[p]+1; anc[x][0]=p; for(auto v:grafo[x]){ if(v==p)continue; dfs(v,x); } fim[x]=tempo; } void get_anc(){ memset(anc,-1,sizeof anc); for(int i = cnt;i>=1;i--){ if(!nivel[i]) dfs(i,i); } for(int j=1;j<20;j++) for(int i=1;i<=cnt;i++) anc[i][j]=anc[anc[i][j-1]][j-1]; } } mn,mx; struct line{ int x, yl, yr, id, tipo; //0=ponto,-1 =close, +1 = open }; vector<line> lines; vector<int> check_validity(int nn, vector<int> X, vector<int> Y,vector<int> S, vector<int> E, vector<int> L, vector<int> R) { n=nn; mn.init();mx.init(); int m = sz(X),q=sz(S); vector<array<int,3>> ed[2]; //criar max mst com arestas = min(a, b) //criar min mst com arestas = max(a, b) for(int i = 0; i < m;i++){ int a = X[i]+1, b = Y[i]+1, c1 = min(a,b),c2=max(a,b); ed[0].pb({c1,a,b});ed[1].pb({c2,a,b}); } sort(all(ed[0]), [&](auto a, auto b){ return a[0] > b[0]; }); sort(all(ed[1])); for(auto w: ed[0]) mx.join(w[1],w[2],w[0]); for(auto w: ed[1]) mn.join(w[1],w[2],w[0]); mx.get_anc(); mn.get_anc(); vector<int> ans(q); for(int i =0;i<q; i++){ int st = S[i]+1, en = E[i]+1, l = L[i]+1, r = R[i]+1; int u=st,v=en; for(int j = 19; j >= 0; j--) if(mx.anc[u][j] != -1 and mx.v[mx.anc[u][j]] >= l) u = mx.anc[u][j]; for(int j = 19; j>=0;j--) if(mn.anc[v][j] != -1 and mn.v[mn.anc[v][j]] <= r) v = mn.anc[v][j]; if(st < l or en > r) continue; lines.pb({mn.ini[v], mx.ini[u], mx.fim[u], i, -1}); lines.pb({mn.fim[v], mx.ini[u], mx.fim[u], i, 1}); } for(int i = 1; i <= n; i++){ lines.pb({mn.ini[i], mx.ini[i], mx.ini[i], i, 0}); } sort(all(lines), [&](auto a, auto b){ if(a.x != b.x) return a.x<b.x; return a.tipo < b.tipo; }); for(int i = 0; i < sz(lines); i++){ if(lines[i].tipo == -1){ ans[lines[i].id] -= query(lines[i].yr); ans[lines[i].id] += query(lines[i].yl - 1); } else if(lines[i].tipo == 1){ ans[lines[i].id] += query(lines[i].yr); ans[lines[i].id] -= query(lines[i].yl -1); } else upd(lines[i].yl,1); } for(int i=0;i<q;i++)ans[i]=min(ans[i],1); 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...