【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。。。坑了我好久啊= =

当练手速= =

你可能感兴趣的:(ZOJ)