Submission #116175

#TimeUsernameProblemLanguageResultExecution timeMemory
116175kig9981Werewolf (IOI18_werewolf)C++17
0 / 100
4086 ms45976 KiB
#include "werewolf.h" #include <bits/stdc++.h> using namespace std; struct Splay { int p, l, r, v, sum; bool inv; Splay() : p(0), l(0), r(0), v(0), sum(0), inv(0) {} } tree[400001]; vector<tuple<int,int,int>> Q[200000], B; vector<int> ans, eidx; bool isRoot(int c) { return tree[c].p==0 || tree[tree[c].p].l!=c && tree[tree[c].p].r!=c; } void update(int c) { tree[c].sum=tree[tree[c].l].sum+tree[tree[c].r].sum+tree[c].v; } void lazy(int c) { if(tree[c].inv) { swap(tree[c].l,tree[c].r); if(tree[c].l) tree[tree[c].l].inv^=1; if(tree[c].r) tree[tree[c].r].inv^=1; tree[c].inv=0; } } void rotate(int c) { int p=tree[c].p; if(tree[p].l==c) { if(tree[c].r) tree[tree[c].r].p=p; tree[p].l=tree[c].r; tree[c].r=p; } else { if(tree[c].l) tree[tree[c].l].p=p; tree[p].r=tree[c].l; tree[c].l=p; } if(!isRoot(p)) (tree[tree[p].p].l==p ? tree[tree[p].p].l:tree[tree[p].p].r)=c; tree[c].p=tree[p].p; tree[p].p=c; update(p); update(c); } void splay(int c) { int cnt=0; while(!isRoot(c)) { int p=tree[c].p; if(!isRoot(p)) lazy(tree[p].p); lazy(p); lazy(c); if(!isRoot(p)) rotate((tree[tree[p].p].l==p)==(tree[p].l==c) ? p:c); rotate(c); //if(++cnt==1000000) exit(0); } lazy(c); } int access(int c) { int ret=c; splay(c); tree[c].r=0; update(c); while(tree[c].p) { splay(ret=tree[c].p); tree[ret].r=c; update(ret); splay(c); } return ret; } int LCA(int a, int b) { access(a); return access(b); } int findRoot(int c) { access(++c); while(tree[c].l) c=tree[c].l; splay(c); return c; } void makeRoot(int c) { access(c); tree[c].inv^=1; } void link(int a, int b) // parent[a]=b { makeRoot(a); access(b); lazy(a); tree[a].l=b; tree[b].p=a; update(a); } void cut(int a) { access(a); tree[tree[a].l].p=0; tree[a].l=0; update(a); } int query(int a, int b) { int lca=LCA(++a,++b), ret=tree[lca].v; access(a); splay(lca); ret+=tree[tree[lca].r].sum; access(b); splay(lca); ret+=tree[tree[lca].r].sum; return ret; } void add_edge(int a, int b, int c) { int e=eidx.back(); eidx.pop_back(); //cout<<"addedge "<<a+1<<' '<<b+1<<'\n'; tree[e]=Splay(); tree[e].v=tree[e].sum=c; link(++a,e); link(++b,e); B.emplace_back(e,a,b); } void restore(int sz) { int e, a, b; while(B.size()>sz) { tie(e,a,b)=B.back(); B.pop_back(); //cout<<"cutedge "<<a<<' '<<b<<'\n'; makeRoot(e); cut(a); cut(b); eidx.push_back(e); } } void solve(vector<pair<int,int>> E, int s, int e) { int m=(s+e)>>1, bsz=B.size(), bsz2; sort(E.begin(),E.end(),[&](pair<int,int> a, pair<int,int> b) { int t1, t2; t1=a.second<s || e<=a.first ? 2:!(a.first<s && e<=a.second); t2=b.second<s || e<=b.first ? 2:!(b.first<s && e<=b.second); return t1>t2; }); if(s==e) { int l, r, idx; for(auto a: E) { if(findRoot(a.first)!=findRoot(a.second)) { add_edge(a.first,a.second,a.first<m && a.second>=m); } } for(auto q: Q[m]) { tie(l,r,idx)=q; ans[idx]=query(l,r)<2; } restore(bsz); return; } vector<pair<int,int>> NE; for(auto a: E) { if(a.second<s || e<=a.first) { if(findRoot(a.first)!=findRoot(a.second)) { add_edge(a.first,a.second,0); NE.push_back(a); } } else if(a.first<s && e<=a.second) { if(findRoot(a.first)!=findRoot(a.second)) { add_edge(a.first,a.second,1); NE.push_back(a); } } else { if(findRoot(a.first)!=findRoot(a.second)) add_edge(a.first,a.second,0); } } restore(bsz); for(auto a: NE) add_edge(a.first,a.second,a.first<s && e<=a.second); bsz2=B.size(); NE.clear(); sort(E.begin(),E.end(),[&](pair<int,int> a, pair<int,int> b) { int t1, t2; t1=a.second<s || e<=a.first ? 2:(a.first<s && e<=a.second); t2=b.second<s || e<=b.first ? 2:(b.first<s && e<=b.second); return t1>t2; }); for(auto a: E) { if(a.second<s || e<=a.first) { if(findRoot(a.first)!=findRoot(a.second)) { add_edge(a.first,a.second,0); } } else if(a.first<s && e<=a.second) { if(findRoot(a.first)!=findRoot(a.second)) { add_edge(a.first,a.second,1); NE.push_back(a); } } else { if(findRoot(a.first)!=findRoot(a.second)) add_edge(a.first,a.second,0); NE.push_back(a); } } restore(bsz2); solve(NE,s,m); solve(NE,m+1,e); restore(bsz); } vector<int> check_validity(int N, vector<int> X, vector<int> Y, vector<int> S, vector<int> E, vector<int> L, vector<int> R) { vector<pair<int,int>> Edge; ans.resize(S.size()); eidx.clear(); for(int i=0;i<N;i++) { Q[i].clear(); tree[i+1]=tree[i+1+N]=Splay(); eidx.push_back(i+1+N); } for(int i=0;i<X.size();i++) Edge.emplace_back(min(X[i],Y[i]),max(X[i],Y[i])); for(int i=0;i<S.size();i++) { if(S[i]<L[i] || R[i]<E[i]) ans[i]=0; else Q[L[i]].emplace_back(S[i],E[i],i); } solve(Edge,0,N-1); return ans; }

Compilation message (stderr)

werewolf.cpp: In function 'bool isRoot(int)':
werewolf.cpp:19:46: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
  return tree[c].p==0 || tree[tree[c].p].l!=c && tree[tree[c].p].r!=c;
                         ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
werewolf.cpp: In function 'void splay(int)':
werewolf.cpp:58:6: warning: unused variable 'cnt' [-Wunused-variable]
  int cnt=0;
      ^~~
werewolf.cpp: In function 'void restore(int)':
werewolf.cpp:146:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  while(B.size()>sz) {
        ~~~~~~~~^~~
werewolf.cpp: In function 'std::vector<int> check_validity(int, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
werewolf.cpp:240:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=0;i<X.size();i++) Edge.emplace_back(min(X[i],Y[i]),max(X[i],Y[i]));
              ~^~~~~~~~~
werewolf.cpp:241:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=0;i<S.size();i++) {
              ~^~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...