SPOJ QTREE

  https://www.spoj.pl/problems/QTREE/

  Splay基础打得差不多之后,第一次搞LCT。

  我的代码跟QZ的太像了囧,我发现我什么都是跟他学的,以至于我俩同时写一个数据结构题交上去就差不多会被判作弊……

  

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <queue>

#define NIL LCT

#define MN 10001

#define MM 20001

#define INF 10000000

using namespace std;



queue<int> q;

int cases,n,pnt[MN],a,b,c;

char s[10];



struct EDGE{

	int pnt,index,cost;

	EDGE *pre;

	EDGE (){}

	EDGE(int _pnt,int _cost,EDGE *_pre,int _index):pnt(_pnt),cost(_cost),pre(_pre),index(_index){}

}Edge[MM],*EP=Edge,*edge[MM];



inline void addedge(int a,int b,int c,int index){

	edge[a]=new(++EP)EDGE(b,c,edge[a],index);

	edge[b]=new(++EP)EDGE(a,c,edge[b],index);

}



struct LinkCutTree{

	struct NODE{

		int val,maxv;

		bool root;

		NODE *left,*right,*father;

		NODE (){}

		NODE(int _val,NODE *_left,NODE *_right,NODE *_father):val(_val),left(_left),right(_right),father(_father){root=true;}

	}LCT[MN],*NP,*node[MN];

	

	void update(NODE *&t){

		t->maxv=max(t->val,max(t->left->maxv,t->right->maxv));

	}

	

	void init(){

		NP=NIL;

		NIL->val=NIL->maxv=-INF;

		NIL->left=NIL->right=NIL->father=NIL;

		NIL->root=false;

		memset(node,0,sizeof(node));

	}

	

	void build(){

		q.push(1);

		node[1]=new(++NP)NODE(-INF,NIL,NIL,NIL);

		while(!q.empty()){

			int i=q.front();q.pop();

			for(EDGE *j=edge[i];j;j=j->pre)

				if(node[j->pnt]!=node[i]->father){

					node[j->pnt]=new(++NP)NODE(j->cost,NIL,NIL,node[i]);

					pnt[j->index]=j->pnt;

					q.push(j->pnt);

				}

		}

	}

	

	void zig(NODE *&t){

		NODE *f=t->father,*r=t->right;

		t->father=f->father;

		if(f->root){

			t->root=true;

			f->root=false;

		}else{

			if(f->father->left==f) f->father->left=t;

			else f->father->right=t;

		}

		t->right=f,f->father=t,f->left=r,r->father=f;

		update(f);

	}

	

	void zag(NODE *&t){

		NODE *f=t->father,*l=t->left;

		t->father=f->father;

		if(f->root){

			t->root=true;

			f->root=false;

		}else{

			if(f->father->left==f) f->father->left=t;

			else f->father->right=t;

		}

		t->left=f;f->father=t,f->right=l,l->father=f;

		update(f);

	}

	

	void splay(NODE *&t){

		while(!t->root){

			if(t->father->root){

				if(t->father->left==t) zig(t);

				else zag(t);

			}else{

				if(t->father->father->left==t->father){

					if(t->father->left==t) zig(t->father),zig(t);

					else zag(t),zig(t);

				}else{

					if(t->father->left==t) zig(t),zag(t);

					else zag(t->father),zag(t);

				}

			}

		}

		update(t);

	}

	

	void Expose(NODE *&t){

		NODE *p=t,*q=NIL;

		while(p!=NIL){

			splay(p);

			p->right->root=true;

			p->right=q;

			p->right->root=false;

			update(p);

			q=p;p=p->father;

		}

	}

	

	void modify(int i,int key){

		node[i]->val=key;

		update(node[i]);

		splay(node[i]);

	}

	

	void query(int a,int b){

		Expose(node[a]);

		NODE *q=NIL,*p=node[b];

		while(p!=NIL){

			splay(p);

			if(p->father==NIL) printf("%d\n",max(p->right->maxv,q->maxv));

			p->right->root=true;

			p->right=q;

			p->right->root=false;

			update(p);

			q=p;p=p->father;

		}

	}

}tree;



void init(){

	EP=Edge;

	memset(edge,0,sizeof(edge));

	memset(pnt,0,sizeof(pnt));

}

		

int main(){

	scanf("%d",&cases);

	while(cases--){

		init();

		tree.init();

		scanf("%d",&n);

		for(int i=1;i<=n;i++){

			scanf("%d%d%d",&a,&b,&c);

			addedge(a,b,c,i);

		}

		tree.build();

		while(scanf("%s",s),s[0]!='D'){

			if(s[0]=='C'){

				scanf("%d%d",&a,&b);

				tree.modify(pnt[a],b);

			}else{

				scanf("%d%d",&a,&b);

				tree.query(a,b);

			}

		}

	}

	return 0;

}

  

你可能感兴趣的:(tree)