【BZOJ】2157: 旅游
http://www.lydsy.com/JudgeOnline/problem.php?id=2157
题解:裸lct不解释..
#include <bits/stdc++.h> using namespace std; struct node *null; struct node { node *c[2], *f; bool flag, rev, tag; int k, sum, mx, mn; bool d() { return f->c[1]==this; } void setc(node *x, bool d) { c[d]=x; x->f=this; } bool check() { return f->c[0]==this || f->c[1]==this; } void upd() { if(this==null) return; tag=!tag; sum=-sum; k=-k; swap(mx, mn); mx=-mx; mn=-mn; } void upd1() { if(this==null) return; rev=!rev; swap(c[0], c[1]); } void pushup() { sum=c[0]->sum+c[1]->sum+k*flag; mx=max(c[0]->mx, c[1]->mx); if(flag) mx=max(mx, k); mn=min(c[0]->mn, c[1]->mn); if(flag) mn=min(mn, k); } void pushdown() { if(tag) c[0]->upd(), c[1]->upd(), tag=0; if(rev) c[0]->upd1(), c[1]->upd1(), rev=0; } }T[2000005], *it=T; node *newnode(int k, bool flag) { node *x=it++; x->c[0]=x->c[1]=x->f=null; x->k=x->sum=k; x->tag=x->rev=0; x->flag=flag; if(flag) x->mx=x->mn=k; else x->mx=-1005, x->mn=1005; return x; } void rot(node *x) { node *f=x->f; f->pushdown(); x->pushdown(); bool d=x->d(); if(f->check()) f->f->setc(x, f->d()); else x->f=f->f; f->setc(x->c[!d], d); x->setc(f, !d); f->pushup(); } void fix(node *x) { if(x->check()) fix(x->f); x->pushdown(); } void splay(node *x) { fix(x); while(x->check()) if(!x->f->check()) rot(x); else x->d()==x->f->d()?(rot(x->f), rot(x)):(rot(x), rot(x)); x->pushup(); } node *access(node *x) { node *y=null; for(; x!=null; y=x, x=x->f) splay(x), x->c[1]=y; return y; } void mkroot(node *x) { access(x)->upd1(); splay(x); } void split(node *x, node *y) { mkroot(x); access(y); splay(y); } void link(node *x, node *y) { mkroot(x); x->f=y; } void init() { null=it++; null->c[0]=null->c[1]=null->f=null; null->k=null->sum=0; null->rev=null->flag=null->tag=0; null->mx=-1005; null->mn=1005; } void change(node *x, int k) { splay(x); x->k=k; x->pushup(); } void update(node *x, node *y) { split(x, y); y->upd(); } void getsum(node *x, node *y) { split(x, y); printf("%d\n", y->sum); } void getmx(node *x, node *y) { split(x, y); printf("%d\n", y->mx); } void getmn(node *x, node *y) { split(x, y); printf("%d\n", y->mn); } node *nd[200005], *ed[200005]; int main() { init(); int n, q; scanf("%d", &n); for(int i=0; i<n; ++i) nd[i]=newnode(0, 0); for(int i=1; i<n; ++i) { int x, y, k; scanf("%d%d%d", &x, &y, &k); ed[i]=newnode(k, 1); link(nd[x], ed[i]); link(ed[i], nd[y]); } scanf("%d", &q); char s[5]; while(q--) { int x, y; scanf("%s%d%d", s, &x, &y); if(s[0]=='C') change(ed[x], y); else if(s[0]=='N') update(nd[x], nd[y]); else if(s[0]=='S') getsum(nd[x], nd[y]); else { if(s[1]=='A') getmx(nd[x], nd[y]); else getmn(nd[x], nd[y]); } } return 0; }
lct倒是半小时1次码好无错误 = =可是坑爹的题 :编号从0~n-1。。。坑了我好久啊= =
当练手速= =
博客地址:www.cnblogs.com/iwtwiioi 本文为博主原创文章,未经博主允许不得转载。一经发现,必将追究法律责任。