Submission #397719

#TimeUsernameProblemLanguageResultExecution timeMemory
397719jeroenodbDancing Elephants (IOI11_elephants)C++14
100 / 100
1932 ms41284 KiB
#include "bits/stdc++.h" #include "elephants.h" using namespace std; #define all(x) begin(x),end(x) template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; } template<typename T_container, typename T = typename enable_if<!is_same<T_container, string>::value, typename T_container::value_type>::type> ostream& operator<<(ostream &os, const T_container &v) { string sep; for (const T &x : v) os << sep << x, sep = " "; return os; } #define debug(a) cerr << "(" << #a << ": " << a << ")\n"; typedef long long ll; typedef vector<int> vi; typedef vector<vi> vvi; typedef pair<int,int> pi; const int mxN = 1e5+1, oo = 1e9; template<class T> struct splaytree { #define l kid(b) #define r kid(b^1) #define L kid(0) #define R kid(1) struct node { T val; node *c[2] = {NULL,NULL}, *par =NULL; bool flip=false,pathtop=true; node(const T& v) : val(v) {} node*& kid(bool k) {return c[k^flip];} node() {} }; static void push(node* at) { if(at->flip) { if(at->L) at->L->flip^=1; if(at->R) at->R->flip^=1; swap(at->L,at->R); at->flip=0; } } static void recalc(node* at) { at->val.recalc(); if(at->L) at->val.recalc(at->L->val); if(at->R) at->val.recalc(at->R->val); } static void print(node* n) { if(n==NULL) return; print(n->L); cout << n->val << ' '; print(n->R); } static void rotate(node* n) { // Precondition: n is not the root, Postcondition: rotates n to the place of its parent // assert(n and !n->pathtop and n->par); node* par = n->par; push(par); push(n); if(!par->pathtop) { auto gp = par->par; if(gp->L==par) gp->L=n; else if(gp->R==par) gp->R=n; } n->par = par->par; bool b= n!=par->L; par->l = n->r; // Fix right child of current node if(n->r) n->r->par = par; n->r = par; // Put parent under current node par->par = n; swap(par->pathtop, n->pathtop); recalc(par); recalc(n); } static void splay(node* n) { while(!n->pathtop) { if(n->par->pathtop) { rotate(n); } else { auto p = n->par, gp = p->par; // Double rotations if((p->L==n) == (gp->L==p)) { rotate(p); } else { rotate(n); } rotate(n); } } push(n); } #undef l #undef r #undef L #undef R }; struct vertex{ int sm=0, id; bool white=false; vertex(int idd, bool b){id=idd, white = b, sm=!b;} vertex(){} void recalc(const vertex& o) { sm += o.sm; } void recalc() { sm = !white; } }; ostream& operator<<(ostream& c, const vertex& v) { return c << v.id << (v.white?"W ":"B "); } struct linkcut { // initially the linkcut tree consists of n disconnected size 1 trees. typedef splaytree<vertex> bst; typedef bst::node node; int n=0; node* t=NULL; linkcut() {} linkcut(int N) { n=N; t = new node[n+1]; // for(int i=0;i<n;++i) { // t[i] = node(vertex()); // } } void add(int i, bool white) { int id = i; if(i>=n and i<2*n) i-=n; t[i] = node(vertex(id,white)); } node* expose(int u) { node *at = NULL, *par = t+u; for(;par; at=par,par = par->par) { bst::splay(par); if(par->kid(1)) { par->kid(1)->pathtop = true; par->kid(1) = NULL; } if(at) at->pathtop = false; par->kid(1) = at; bst::recalc(par); } bst::splay(t+u); return t+u; } void reroot(int u) { node* root = expose(u); root->flip^=1; } void link(int u, int v) { reroot(u); t[u].par = t+v; // connect with unmarked edge } void cut(int u, int v) { reroot(u); expose(v); node* at = t+v; assert(at->kid(0) == t+u); if(at->kid(0)) { auto& prev = at->kid(0); prev->par=NULL; prev->pathtop = true; prev = NULL; } bst::recalc(at); } ll calc(int u, int v) { reroot(u); auto root = expose(v); // bst::print(root); return root->val.sm; } }; int n,l; map<pi,int> m; linkcut lc; vi xs; void init(int N, int L, int X[]) { l=L; lc = linkcut(N*2+2); n = N; xs = vi(X,X+n); lc.add(n*2,true), lc.add(n*2+1,true); for(int i=0;i<n;++i) { int x = X[i]; m[{x,i}] = i; m[{x+L,i+n}]= i+n; lc.add(i,false), lc.add(i+n,true); lc.link(i,i+n); } m[{-2*oo,n*2}] = n*2; m[{oo*2,n*2+1}] = n*2+1; for(int i=0;i<n;++i) { auto iter = m.upper_bound({X[i]+L,i+n}); lc.link(i+n,iter->second); } auto iter = m.upper_bound({-2*oo+L,2*n}); lc.link(n*2,iter->second); } int update(int i, int y) { int X = xs[i]; // white node -> cut lc.cut(i+n,m.upper_bound({X+l,i+n})->second); auto fix = [](int x, int j) { auto iter = m.find({x,j}); auto maybe = prev(iter); m.erase(iter); if(maybe->second>=n) { // node is white and thus connected lc.cut(j, maybe->second); lc.link(maybe->second, next(maybe)->second); } }; fix(X+l,i+n); fix(X,i); xs[i] = y; // debug(xs); auto fix2 = [](int x, int j) { auto iter = m.lower_bound({x,j}); auto maybe = prev(iter); if(maybe->second>=n) { // node is white and thus connected lc.cut(maybe->second, next(maybe)->second); lc.link(maybe->second, j); } m[{x,j}] = j; }; auto iter = m.upper_bound({y+l,i+n}); lc.link(i+n,iter->second); fix2(y+l,i+n); fix2(y,i); return lc.calc(n*2,n*2+1); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...