【BZOJ 2843】极地旅行社
复习一下Link Cut Tree的模板。
#include<cstdio> #include<cstring> #include<algorithm> #define N 30003 #define read(x) x=getint() using namespace std; struct node *null; struct node { node *ch[2], *fa; int d, sum; short rev; bool pl() {return fa->ch[1] == this;} bool check() {return fa == null || (fa->ch[0] != this && fa->ch[1] != this);} void setc(node *r, bool c) {ch[c] = r; r->fa = this;} void push() { if (rev) { rev = 0; swap(ch[0], ch[1]); ch[0]->rev ^= 1; ch[1]->rev ^= 1; } } void count() {sum = ch[0]->sum + ch[1]->sum + d;} }; node pool[N]; int n; inline int getint() { int k = 0, fh = 1; char c = getchar(); for(; c < '0' || c > '9'; c = getchar()) if (c == '-') fh = -1; for(; c >= '0' && c <= '9'; c = getchar()) k = k * 10 + c - '0'; return k * fh; } namespace LCT { void Build() { null = &pool[0]; null->ch[0] = null->ch[1] = null->fa = null; null->d = null->sum = null->rev = 0; read(n); for(int i = 1; i <= n; ++i) { read(pool[i].d); pool[i].ch[0] = pool[i].ch[1] = pool[i].fa = null; pool[i].sum = pool[i].rev = 0; } } void rotate(node *r) { node *f = r->fa; bool c = r->pl(); if (f->check()) r->fa = f->fa; else f->fa->setc(r, f->pl()); f->setc(r->ch[!c], c); r->setc(f, !c); f->count(); } void update(node *r) {if (!r->check()) update(r->fa); r->push();} void splay(node *r) { update(r); for(; !r->check(); rotate(r)) if (!r->fa->check()) rotate(r->pl() == r->fa->pl() ? r->fa : r); r->count(); } node *access(node *r) { node *y = null; for(; r != null; y = r, r = r->fa) splay(r), r->ch[1] = y; return y; } node *findrt(node *r) { access(r); splay(r); while (r->ch[0] != null) r = r->ch[0]; return r; } void changert(node *r) { access(r)->rev ^= 1; splay(r); } void link(node *r, node *t) { changert(r); r->fa = t; } } int main() { LCT::Build(); int m = getint(), a, b; node *aa, *bb; char c; for(int i = 1; i <= m; ++i) { for(c = getchar(); c < 'a' || c > 'z'; c = getchar()); read(a); read(b); switch (c) { case 'b': if (LCT::findrt(&pool[a]) == LCT::findrt(&pool[b])) puts("no"); else {puts("yes"); LCT::link(&pool[a], &pool[b]);} break; case 'p': LCT::changert(&pool[a]); pool[a].d = b; pool[a].count(); break; case 'e': if (LCT::findrt(&pool[a]) != LCT::findrt(&pool[b])) puts("impossible"); else { LCT::changert(&pool[a]); LCT::access(&pool[b]); LCT::splay(&pool[b]); printf("%d\n",pool[b].sum); } break; } } return 0; }
水啊水~~~
NOI 2017 Bless All