COJ 1006 树上操作

传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=979

 

WZJ的数据结构(六)
难度级别:D; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
试题描述

给你一棵N个节点的无根树,边之间有权值。请你设计一个数据结构,进行以下两种操作:

1.修改:给你a、b,将第a条边的权值改为b。

2.询问:给你a、b,输出从a到b路径上的最大值、最小值与权值和,如果a=b,输出"error"。

输入
第一行为一个正整数N。
接下来N-1行为每一条边,每行3个正整数a,b,c,表示有一条从a到b权值为c的边(从1开始编号)。
第N+1行为一个正整数Q,表示Q次操作。
接下来Q行为每一次询问,每行3个正整数t,a,b,若t=1表示询问,t=0表示修改。
输出
对于每一次询问,输出三个正整数,即最大值、最小值与权值和,如果a=b,输出"error"。
输入示例

1 2 4
1 4 5
3 4 6
2 5 7
4
1 1 5
1 2 5
0 1 2
1 1 5
输出示例
7 4 11
7 7 7
7 2 9
其他说明
1<=N,Q<=50000
1<=c<=1000
询问中的1<=a,b<=N
修改中的1<=a<=N-1,1<=b<=1000

题解:懒得写树链剖分了LCT走起

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<cstring>
  7 #define PAU putchar(' ')
  8 #define ENT putchar('\n')
  9 using namespace std;
 10 const int maxn=100000+10,inf=-1u>>1;
 11 inline int read(){
 12     int x=0,sig=1;char ch=getchar();
 13     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
 14     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
 15     return x*=sig;
 16 }
 17 inline void write(int x){
 18     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
 19     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
 20     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
 21 }
 22 struct node {
 23     int x,mi,mx,sm,set;bool rev;
 24     node *ch[2],*fa;
 25     inline void add_rev_tag(){
 26         swap(ch[0],ch[1]);rev^=1;return;
 27     }
 28     inline void add_set_tag(int a){
 29         x=set=a;
 30         if(mi!=inf) mi=set;
 31         if(mx!=-inf) mx=set;
 32     }
 33     inline void down(){
 34         if(rev){
 35             if(ch[0]) ch[0]->add_rev_tag();
 36             if(ch[1]) ch[1]->add_rev_tag();
 37             rev=0;
 38         }
 39         if(set){
 40             if(ch[0]) ch[0]->add_set_tag(set);
 41             if(ch[1]) ch[1]->add_set_tag(set);
 42             set=0;
 43         }
 44         return;
 45     }
 46     inline void update(){
 47         sm=x;mi=inf;mx=-inf;
 48         if(ch[0]) sm+=ch[0]->sm,mi=min(mi,ch[0]->mi),mx=max(mx,ch[0]->mx);
 49         if(ch[1]) sm+=ch[1]->sm,mi=min(mi,ch[1]->mi),mx=max(mx,ch[1]->mx);
 50         if(!x) return;
 51         mi=min(x,mi);
 52         mx=max(x,mx);
 53         return;
 54     }
 55 }lct[maxn];
 56 inline int get_parent(node *x,node *&fa){return (fa=x->fa)?fa->ch[0]==x?0:fa->ch[1]==x?1:-1:-1;}
 57 inline void rotate(node *x){
 58     int t1,t2;
 59     node *fa,*gfa;
 60     t1=get_parent(x,fa);
 61     t2=get_parent(fa,gfa);
 62     if ((fa->ch[t1]=x->ch[t1^1])) fa->ch[t1]->fa=fa;
 63     x->ch[t1^1]=fa;fa->fa=x;x->fa=gfa;
 64     if (t2!=-1) gfa->ch[t2]=x;
 65     fa->update();return;
 66 }
 67 inline void pushdown(node *x){
 68     static node *stack[maxn];
 69     int cnt=0;
 70     while(1){
 71         stack[cnt++]=x;
 72         node *fa=x->fa;
 73         if (!fa || (fa->ch[0]!=x && fa->ch[1]!=x)) break;
 74         x=fa;
 75     }
 76     while(cnt--) stack[cnt]->down();
 77     return;
 78 }
 79 inline node * splay(node *x){
 80     pushdown(x);
 81     while(1){
 82         int t1,t2;
 83         node *fa,*gfa;
 84         t1=get_parent(x,fa);
 85         if(t1==-1) break;
 86         t2=get_parent(fa,gfa);
 87         if(t2==-1){
 88             rotate(x);break;
 89         } else if (t1==t2){
 90             rotate(fa);rotate(x);
 91         } else{
 92             rotate(x);rotate(x);
 93         }
 94     }
 95     x->update();
 96     return x;
 97 }
 98 inline node * access(node *x){
 99     node *ret=NULL;
100     while (x) splay(x)->ch[1]=ret,(ret=x)->update(),x=x->fa;
101     return ret;
102 }
103 inline void makeroot(int x){access(lct+x)->add_rev_tag();}
104 inline void link(int u,int v){
105     makeroot(u);splay(lct+u)->fa=lct+v;return;
106 }
107 int n,q;
108 int main(){
109     n=read();
110     int i;
111     int lim=n<<1;
112     for(i=1;i<=lim;i++) {
113         lct[i]=(node){0,inf,-inf,0,0,0};
114     }
115     for(i=1;i<n;i++){
116         int u,v,w;
117         u=read();v=read();
118         link(u,i+n);link(v,i+n);lct[i+n].add_set_tag(read());
119     }
120     q=read();
121     int x,y,c;
122     while(q--){
123         c=read();x=read();y=read();
124         if(c==0) makeroot(x+n),access(x+n+lct)->add_set_tag(y);
125         else{
126             if(x==y){puts("error");continue;}
127             makeroot(x);node*t=access(y+lct);
128             write(t->mx);PAU;write(t->mi);PAU;write(t->sm);ENT;
129         }
130     }
131     return 0;
132 }

 

你可能感兴趣的:(操作)