lct树上查询最大值和路径长

Posted mzh2017

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lct树上查询最大值和路径长相关的知识,希望对你有一定的参考价值。

技术分享图片
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define ll long long
  4 #define M 1000001
  5 struct tonod{
  6     int fa,ch[2],sum,maxx,key;
  7     bool rev,is_root;
  8 }tree[M];
  9 int gs(int x){return x==tree[tree[x].fa].ch[1];}
 10 void pushrev(int x){
 11     if(!x)return;
 12     swap(tree[x].ch[0],tree[x].ch[1]);
 13     tree[x].rev^=1;
 14 }
 15 void pushdown(int x){
 16     if(tree[x].rev){
 17         pushrev(tree[x].ch[0]);
 18         pushrev(tree[x].ch[1]);
 19         tree[x].rev=0;
 20     }
 21 }
 22 void update(int x){
 23     tree[x].maxx=tree[x].key;
 24     tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].key;
 25     if(tree[x].ch[0]){
 26         tree[x].maxx=max(tree[tree[x].ch[0]].maxx,tree[x].maxx);
 27     }
 28     if(tree[x].ch[1]) tree[x].maxx=max(tree[x].maxx,tree[tree[x].ch[1]].maxx);
 29 }
 30 void rotate(int x){
 31     if(tree[x].is_root)return;
 32     int k=gs(x),fa=tree[x].fa;
 33     int fafa=tree[fa].fa;
 34     pushdown(fa);pushdown(x);
 35     tree[fa].ch[k]=tree[x].ch[k^1];
 36     if(tree[x].ch[k^1])tree[tree[x].ch[k^1]].fa=fa;
 37     tree[x].ch[k^1]=fa;
 38     tree[fa].fa=x;
 39     tree[x].fa=fafa;
 40     if(!tree[fa].is_root)tree[fafa].ch[fa==tree[fafa].ch[1]]=x;
 41     else tree[x].is_root=1,tree[fa].is_root=0;
 42     update(fa);update(x);
 43 }
 44 void push(int x){
 45     if(!tree[x].is_root)push(tree[x].fa);
 46     pushdown(x);
 47 }
 48 void splaying(int x){
 49     push(x);
 50     for(int fa;!tree[x].is_root;rotate(x)){
 51         if(!tree[fa=tree[x].fa].is_root){
 52             rotate((gs(x)==gs(fa))?fa:x);
 53         }
 54     }
 55 }
 56 void access(int x){
 57     int y=0;
 58     do{
 59         splaying(x);
 60         tree[tree[x].ch[1]].is_root=1;
 61         tree[tree[x].ch[1]=y].is_root=0;
 62         update(x);
 63         x=tree[y=x].fa;
 64     }while(x);
 65 }
 66 void moveroot(int x){
 67     access(x);
 68     splaying(x);
 69     pushrev(x);
 70 }
 71 void link(int u,int v){
 72     moveroot(u);
 73     tree[u].fa=v;
 74 }
 75 void cut(int u,int v){
 76     moveroot(u);
 77     access(v);splaying(v);
 78     pushdown(v);
 79     tree[u].fa=tree[v].ch[0]=0;
 80     update(v);
 81 }
 82 void insert(int x,int key){
 83     tree[x].sum=tree[x].maxx=tree[x].key=key;
 84     splaying(x);update(x);
 85 }
 86 int query_max(int x,int y){
 87     moveroot(x);access(y);splaying(y);
 88     printf("%d
",tree[y].maxx);
 89 }
 90 int query_sum(int x,int y){
 91     moveroot(x);access(y);splaying(y);
 92     printf("%d
",tree[y].sum);
 93 }
 94 int main(){
 95     int n;
 96     scanf("%d",&n);
 97     for(int i=1;i<=n;i++)
 98     tree[i].is_root=1;
 99     for(int i=1,a,b;i<n;i++)
100     scanf("%d%d",&a,&b),link(a,b);
101     for(int i=1,a;i<=n;i++)
102     scanf("%d",&a),insert(i,a);
103     int m;
104     scanf("%d",&m);
105     while(m--){
106         char tp[10];
107         scanf("%s",tp);
108         if(tp[0]==C){
109             int x,y;
110             scanf("%d%d",&x,&y);
111             insert(x,y);
112         }
113         else if(tp[1]==M){
114             int x,y;
115             scanf("%d%d",&x,&y);
116             query_max(x,y);
117         }else{
118             int x,y;
119             scanf("%d%d",&x,&y);
120             query_sum(x,y);
121         }
122     }
123 }
hh

 

以上是关于lct树上查询最大值和路径长的主要内容,如果未能解决你的问题,请参考以下文章

SP2666 QTREE4 - Query on a tree IV(LCT)

Luogu4712 WC2006 水管局长 LCT

洛谷.4234.最小差值生成树(LCT)

[UOJ274]温暖会指引我们前行

LCT 维护边双 / 点双的模板

洛谷P3348 [ZJOI2016]大森林(LCT,虚点,树上差分)