QTREE系列题解

打了快一星期的qtree终于打完了- - (其实还有两题改不出来弃疗了QAQ)

orz神AK一星期前就虐完QTREE

避免忘记还是简单写下题解吧0 0

QTREE1

题意:

给出一颗带边权树

一个操作:修改边权

还有一个询问:求x到y路径上边权最大值

树链剖分模版题- -blabla

代码:

  1 #include <cstdio>
  2 #include <cstring>
  3 const int N=10001;
  4 struct inli{
  5     int next,data,lon;
  6     inli(const int a=0,const int b=0,const int c=0):
  7         next(a),data(b),lon(c){}
  8 }line[N*2];
  9 struct info{
 10     int x,y;
 11     info(const int a=0,const int b=0):
 12         x(a),y(b){}
 13 }sline[N];
 14 int n,t,nl,dfss,back[N],tree[N*4],deep[N],num[N],hard[N],dfn[N],fl[N],fat[N],gr[N],son[N];
 15 int st,si;
 16 char s[10];
 17 int max(int x,int y){ return x>y ? x : y; }
 18 void swap(int &x,int &y){ int t=x; x=y,y=t; }
 19 void clean(){
 20     nl=dfss=0;
 21     memset(son,0,sizeof(son));
 22     memset(hard,0,sizeof(hard));
 23     memset(tree,0,sizeof(tree));
 24 }
 25 void makehard(int t){
 26     num[t]=1;
 27     for (int i=son[t];i;i=line[i].next)
 28     if (line[i].data!=fat[t]){
 29         int ne=line[i].data;
 30         fat[ne]=t;
 31         deep[ne]=deep[t]+1;
 32         fl[ne]=line[i].lon;
 33         makehard(ne);
 34         num[t]+=num[ne];
 35         if (num[hard[t]]<num[ne]) hard[t]=ne;
 36     }
 37 }
 38 void dfs(int t,int gra){
 39     dfn[t]=++dfss;
 40     back[dfss]=t;
 41     gr[t]=gra;
 42     if (hard[t]) dfs(hard[t],gra);
 43     for (int i=son[t];i;i=line[i].next){
 44         int ne=line[i].data;
 45         if (ne!=fat[t] && ne!=hard[t]) dfs(ne,ne);
 46     }
 47 }
 48 void build(int l,int r,int rt){
 49     if (l==r-1){
 50         tree[rt]=fl[back[r]];
 51         return;
 52     }
 53     int mid=(l+r)/2;
 54     build(l,mid,rt*2);
 55     build(mid,r,rt*2+1);
 56     tree[rt]=max(tree[rt*2],tree[rt*2+1]);
 57 }
 58 int getmax(int l,int r,int rt,int x,int y){
 59     if (x==y) return 0;
 60     if (x<=l && r<=y) return tree[rt];
 61     int mid=(l+r)/2,res=0;
 62     if (x<mid) res=max(res,getmax(l,mid,rt*2,x,y));
 63     if (mid<y) res=max(res,getmax(mid,r,rt*2+1,x,y));
 64     return res;
 65 }
 66 int getans(int x,int y){
 67     if (x==y) return 0;
 68     if (gr[x]==gr[y]){
 69         if (deep[x]>deep[y]) swap(x,y);
 70         return getmax(1,n,1,dfn[x],dfn[y]);
 71     }
 72     if (deep[gr[x]]<deep[gr[y]]) swap(x,y);
 73     return max(getans(fat[gr[x]],y),max(getmax(1,n,1,dfn[gr[x]],dfn[x]),fl[gr[x]]));
 74 }
 75 void change2(int l,int r,int rt,int x,int y){
 76     if (l+1==r) return (void)(tree[rt]=y);
 77     int mid=(l+r)/2;
 78     if (x<mid) change2(l,mid,rt*2,x,y);
 79     else change2(mid,r,rt*2+1,x,y);
 80     tree[rt]=max(tree[rt*2],tree[rt*2+1]);
 81 }
 82 void change(int t,int s){
 83     int x=sline[t].x,y=sline[t].y;
 84     if (deep[x]>deep[y]) swap(x,y);
 85     if (gr[x]==gr[y]) change2(1,n,1,dfn[x],s);
 86     else fl[y]=s;
 87 }
 88 int main(){
 89     freopen("spoj375.in","r",stdin);
 90     freopen("spoj375.out","w",stdout);
 91     for (scanf("%d",&t);t;t--){
 92         clean();
 93         scanf("%d
",&n);
 94         int x,y,z;
 95         for (int i=1;i<n;i++){
 96             scanf("%d%d%d
",&x,&y,&z);
 97             line[++nl]=inli(son[x],y,z),son[x]=nl;
 98             line[++nl]=inli(son[y],x,z),son[y]=nl;
 99             sline[i]=info(x,y);
100         }
101         makehard(1);
102         dfs(1,1);
103         build(1,n,1);
104         int i=0;
105         while (1){
106             si=++i;
107             st=t;
108             if (i==9995)
109             i=9995;
110             if (t==2)
111             t=2;
112             if (t==9 && i==9999)
113             t=9;
114             scanf("%s",s);
115             if (s[0]=='Q'){
116                 scanf("%d%d
",&x,&y);
117                 printf("%d
",getans(x,y));
118             }
119             if (s[0]=='C'){
120                 scanf("%d%d
",&x,&y);
121                 change(x,y);
122             }
123             if (s[0]=='D') break;
124             if (n==2)
125             n=2;
126         }
127     }
128     fclose(stdin);
129     fclose(stdout);
130 }
View Code

QTREE2

题意:

给出一颗带边权树 两个询问

1.求x到y路径上边权和

2.求x到y路径上的第k条边的边权

边权和还是树链剖分模版- -

求第k条边 刚想了一下貌似树剖也能做 但是我是用倍增的


代码:

  1 #include <cstdio>
  2 #include <cstring>
  3 const int N=10001;
  4 struct inli{
  5     int next,data,lon;
  6     inli(const int a=0,const int b=0,const int c=0):
  7         next(a),data(b),lon(c){}
  8 }line[N*2];
  9 int t,n,nl,deep[N],son[N],fat[N][20],dis[N][20];
 10 char s[10];
 11 void swap(int &x,int &y){ int t=x; x=y,y=t; }
 12 void clean(){
 13     nl=0;
 14     for (int i=1;i<=n;i++){
 15         son[i]=0;
 16         memset(fat[i],0,sizeof(fat[i]));
 17     }
 18 }
 19 void makefat(int t){
 20     for (int i=1;fat[fat[t][i-1]][i-1];++i){
 21         fat[t][i]=fat[fat[t][i-1]][i-1];
 22         dis[t][i]=dis[t][i-1]+dis[fat[t][i-1]][i-1];
 23     }
 24     for (int i=son[t];i;i=line[i].next)
 25     if (line[i].data!=fat[t][0]){
 26         int ne=line[i].data;
 27         deep[ne]=deep[t]+1;
 28         fat[ne][0]=t;
 29         dis[ne][0]=line[i].lon;
 30         makefat(ne);
 31     }
 32 }
 33 int getdis(int x,int y){
 34     if (x==y) return 0;
 35     if (deep[x]!=deep[y]){
 36         if (deep[x]<deep[y]) swap(x,y);
 37         int i=0;
 38         for (;deep[fat[x][i]]>=deep[y] && fat[x][i];++i);
 39         --i;
 40         return dis[x][i]+getdis(fat[x][i],y);
 41     }
 42     if (fat[x][0]==fat[y][0]) return dis[x][0]+dis[y][0];
 43     int i=0;
 44     for (;fat[x][i]!=fat[y][i] && fat[x][i];++i);
 45     --i;
 46     return dis[x][i]+dis[y][i]+getdis(fat[x][i],fat[y][i]);
 47 }
 48 int getgr(int x,int y){
 49     if (x==y) return x;
 50     if (deep[x]!=deep[y]){
 51         if (deep[x]<deep[y]) swap(x,y);
 52         int i=0;
 53         for (;deep[fat[x][i]]>=deep[y] && fat[x][i];++i);
 54         --i;
 55         return getgr(fat[x][i],y);
 56     }
 57     if (fat[x][0]==fat[y][0]) return fat[x][0];
 58     int i=0;
 59     for (;fat[x][i]!=fat[y][i] && fat[x][i];++i);
 60     --i;
 61     return getgr(fat[x][i],fat[y][i]);
 62 }
 63 int getans(int t,int s){
 64     if (s==1) return t;
 65     int i=0;
 66     for (;deep[t]-deep[fat[t][i]]+1<=s && fat[t][i];++i);
 67     --i;
 68     return getans(fat[t][i],s-(deep[t]-deep[fat[t][i]]));
 69 }
 70 int main(){
 71     freopen("spoj913.in","r",stdin);
 72     freopen("spoj913.out","w",stdout);
 73     for (scanf("%d",&t);t;t--){
 74         scanf("%d
",&n);
 75         clean();
 76         int x,y,z;
 77         for (int i=1;i<n;i++){
 78             scanf("%d%d%d
",&x,&y,&z);
 79             line[++nl]=inli(son[x],y,z),son[x]=nl;
 80             line[++nl]=inli(son[y],x,z),son[y]=nl;
 81         }
 82         makefat(1);
 83         while (1){
 84             scanf("%s",s);
 85             if (s[1]=='I'){
 86                 scanf("%d%d
",&x,&y);
 87                 printf("%d
",getdis(x,y));
 88             }
 89             if (s[0]=='K'){
 90                 scanf("%d%d%d
",&x,&y,&z);
 91                 int gr=getgr(x,y);
 92                 if (deep[x]-deep[gr]+1<z){
 93                     swap(x,y);
 94                     z=deep[x]+deep[y]-deep[gr]*2+2-z;
 95                 }
 96                 printf("%d
",getans(x,z));
 97             }
 98             if (s[1]=='O') break;
 99         }
100         puts("");
101     }
102     fclose(stdin);
103     fclose(stdout);
104 }
View Code

QTREE3

题意:

给出一颗点初始全白的树

一个操作:修改点的颜色

一个询问:求1到点x的最近黑点 没有则输出-1

这题我觉得能用动态树做

询问的时候把x access到根 splay上维护深度最小的黑点

树链剖分也可以做 线段树维护最前面的黑点即可(貌似比较简单- -)

这题我貌似就yy了一下没打- -

QTREE4

题意:

给出一颗点初始全白的带边权树

一个操作:修改点的颜色

一个询问:求最远的两个白色点的距离

QAQ这题被spoj卡时了啊 根本调不出来- -

其实这题好像是去湖南培训的一道题的弱化版- - 我竟然没想出来orz

我的做法是点分治+3*堆

我们定义某重心的子树的重心是 该重心的重儿子 反之重父亲 

维护第一个堆que1维护 该点管辖范围内的点到该点重父亲的距离最大值 

第二个堆que2维护 该点的每个重儿子的que1的堆顶的最大值(如果该点为白点 要插入一个dis为0的值)

每个que2的前2大的距离和即为两白点经过该点答案

第三个堆ans3就维护所有的que2的前2大的距离和的最大值

因为我用的是priority_queue 所以不支持删除- - 于是我就每个对打了一个时间戳

一修改3个堆一个套一个全部要改 整个世界格局混乱orz 思路不清晰就很容易晕

这题我打了3天啊QAQ(最后还没调出来←_←)

这题没A就不贴代码了- -

QTREE5

题意:

给出一颗点初始全白的带边权树

一个操作:修改点的颜色

一个询问:求离点x最远的白点的距离

这题和上题做法差不多 枚举管辖范围包括x的重心即可

因为上一题被卡时了 - - 这题也不敢打orz

QTREE6

题意:

给出一颗点初始全白的树

一个操作:修改点的颜色

一个询问:求点x与多少点相连 两点相连条是这两点的路径上的点都与点x的颜色相同

这题我是用树链剖分做的

维护f[2][i]表示i点为黑色或白色时 i的子树中与i相连的点的个数

那么x点的答案就是x点的最浅相连祖先的f[col[x]]值

当修改某点的颜色时 就修改该点到最浅相连祖先的父亲的f值即可

这题也可以用动态树做

详见QTREE7- - 233为什么和神ak写的一样

代码:

  1 #include <cstdio>
  2 const int N=100001;
  3 struct inli{
  4     int next,data;
  5     inli(const int a=0,const int b=0):
  6         next(a),data(b){}
  7 }line[N*2];
  8 int n,m,nl,dfss,deep[N],gr[N],hard[N],num[N],back[N],dfn[N],son[N],tree[2][N*4],fat[N][20],coltree[N*4],col[N];
  9 void makehard(int t){
 10     for (int i=1;fat[fat[t][i-1]][i-1];++i) fat[t][i]=fat[fat[t][i-1]][i-1];
 11     num[t]=1;
 12     for (int i=son[t];i;i=line[i].next)
 13     if (line[i].data!=fat[t][0]){
 14         int ne=line[i].data;
 15         fat[ne][0]=t;
 16         deep[ne]=deep[t]+1;
 17         makehard(ne);
 18         num[t]+=num[ne];
 19         if (num[ne]>num[hard[t]]) hard[t]=ne;
 20     }
 21 }
 22 void dfs(int t,int gra){
 23     gr[t]=gra;
 24     dfn[t]=++dfss;
 25     back[dfss]=t;
 26     if (hard[t]) dfs(hard[t],gra);
 27     for (int i=son[t];i;i=line[i].next){
 28         int ne=line[i].data;
 29         if (ne!=fat[t][0] && ne!=hard[t]) dfs(ne,ne);
 30     }
 31 }
 32 
 33 void pushdown(int t){
 34     tree[0][t*2]+=tree[0][t];
 35     tree[0][t*2+1]+=tree[0][t];
 36     tree[0][t]=0;
 37     tree[1][t*2]+=tree[1][t];
 38     tree[1][t*2+1]+=tree[1][t];
 39     tree[1][t]=0;
 40 }
 41 void build(int l,int r,int rt){
 42     if (l==r){
 43         tree[0][rt]=num[back[l]];
 44         tree[1][rt]=1;
 45         return;
 46     }
 47     int mid=(l+r)/2;
 48     build(l,mid,rt*2);
 49     build(mid+1,r,rt*2+1);
 50 }
 51 int getgr(int l,int r,int rt,int x,int y,int z){
 52     int mid=(l+r)/2,res;
 53     if (x<=l && r<=y){
 54         if (coltree[rt]==z) return l;
 55         if (l==r) return -1;
 56         if (coltree[rt*2+1]!=z) return getgr(mid+1,r,rt*2+1,x,y,z);
 57         res=getgr(l,mid,rt*2,x,y,z);
 58         return res==-1 ? mid+1 : res;
 59     }
 60     if (y<=mid) return getgr(l,mid,rt*2,x,y,z);
 61     if (x>mid) return getgr(mid+1,r,rt*2+1,x,y,z);
 62     res=getgr(mid+1,r,rt*2+1,x,y,z);
 63     if (res==-1) return -1;
 64     if (res>mid+1) return res;
 65     res=getgr(l,mid,rt*2,x,y,z);
 66     return res==-1 ? mid+1 : res;
 67 }
 68 int getans(int l,int r,int rt,int x,int y){
 69     if (l==r) return tree[y][rt];
 70     int mid=(l+r)/2;
 71     pushdown(rt);
 72     if (x<=mid) return getans(l,mid,rt*2,x,y);
 73     else return getans(mid+1,r,rt*2+1,x,y);
 74 }
 75 void addtree(int l,int r,int rt,int x,int y,int z,int co){
 76     if (x<=l && r<=y) return (void)(tree[co][rt]+=z);
 77     int mid=(l+r)/2;
 78     pushdown(rt);
 79     if (x<=mid) addtree(l,mid,rt*2,x,y,z,co);
 80     if (mid<y) addtree(mid+1,r,rt*2+1,x,y,z,co);
 81 }
 82 void changecol(int l,int r,int rt,int x){
 83     if (l==r) return (void)(coltree[rt]^=1);
 84     int mid=(l+r)/2;
 85     if (x<=mid) changecol(l,mid,rt*2,x);
 86     else changecol(mid+1,r,rt*2+1,x);
 87     coltree[rt]=coltree[rt*2]==coltree[rt*2+1] ? coltree[rt*2] : -1;
 88 }
 89 
 90 int getfat(int t,int co){
 91     if (!fat[t][0] || col[fat[t][0]]!=co)  return t;
 92     int save=back[getgr(1,n,1,dfn[gr[t]],dfn[t],co)];
 93     if (save!=gr[t] || !fat[gr[t]][0] || col[fat[gr[t]][0]]!=co) return save;
 94     else return getfat(fat[gr[t]][0],co);
 95 }
 96 void add(int co,int x,int y,int s){
 97     if (deep[x]>deep[y]) return;
 98     if (gr[x]==gr[y]){
 99         addtree(1,n,1,dfn[x],dfn[y],s,co);
100         return;
101     }
102     addtree(1,n,1,dfn[gr[y]],dfn[y],s,co);
103     add(co,x,fat[gr[y]][0],s);
104 }
105 void change(int t){
106     int p1=getans(1,n,1,dfn[t],col[t]),p2=getans(1,n,1,dfn[t],col[t]^1);
107     /*if (fat[t][0]){
108         if (col[fat[t][0]]==col[t]) add(col[t]^1,fat[t][0],fat[t][0],p2);
109         else add(col[t],fat[t][0],fat[t][0],-p1);
110     }*/
111     int fa=getfat(t,col[t]);
112     if (fat[fa][0]) fa=fat[fa][0];
113     add(col[t],fa,fat[t][0],-p1);
114     col[t]^=1;
115     changecol(1,n,1,dfn[t]);
116     fa=getfat(t,col[t]);
117     if (fat[fa][0]) fa=fat[fa][0];
118     add(col[t],fa,fat[t][0],p2);
119 }
120 int main(){
121     freopen("spoj16549.in","r",stdin);
122     freopen("spoj16549.out","w",stdout);
123     scanf("%d",&n);
124     for (int x,y,i=1;i<n;i++){
125         scanf("%d%d",&x,&y);
126         line[++nl]=inli(son[x],y),son[x]=nl;
127         line[++nl]=inli(son[y],x),son[y]=nl;
128     }
129     deep[1]=1;
130     makehard(1);
131     dfs(1,1);
132     build(1,n,1);
133     scanf("%d",&m);
134     for (int x,y,i=1;i<=m;i++){
135         scanf("%d%d",&x,&y);
136         if (i==2)
137         i=2;
138         if (x) change(y);
139         else printf("%d
",getans(1,n,1,dfn[getfat(y,col[y])],col[y]));
140     }
141     fclose(stdin);
142     fclose(stdout); 
143 }
View Code

QTREE7

题意:

给出一颗点为黑色或白色的带点权的树

两个操作:

1.修改点的颜色

2.修改点权

一个询问:

求点与x相连的点的最大点权 两点相连条是这两点的路径上的点都与点x的颜色相同

把黑点和白点建成两颗树 同色的相连点就在同一颗树上

用set维护某点的轻边子树的最大值(取每个轻边子树的最大点权存进set)

再用动态树splay维护重边上的点最大值

询问时把该点access到根 再splay求出答案即可

access的时候要注意 当修改重边时 set要删除原轻边的最大值 加上原重边的最大值

修改点权也很好处理 - -稍微想想就知道了

修改颜色 则需要从某颜色的树上cut下一个点 再在另外颜色的树上link上一个点

但是当图为菊花图时link上的点的轻边个数可能有O(n)个 在set上一个个插入 一次操作就需要O(nlogn) 显然tle

orz神ak想到一种特别好的方法

在黑数上如果某点有个儿子的颜色为黑色就保留该点 白树同理 这样每次修改在set上就只会插入或删除一个点 就能过了

代码:

  1 #include <cstdio>
  2 #include <set>
  3 using namespace std;
  4 const int N=100001;
  5 struct intr{
  6     int fat,lc,rc,t,max,root;
  7     intr(const int a=0,const int b=0,const int c=0,const int d=0,const int e=0,const int f=1):
  8         fat(a),lc(b),rc(c),t(d),max(e),root(f){}
  9 };
 10 struct inli{
 11     int next,data;
 12     inli(const int a=0,const int b=0):
 13         next(a),data(b){}
 14 }line[N*2];
 15 int n,m,nl,son[N],col[N],fat[N];
 16 int max(int x,int y){ return x>y ? x : y; }
 17 struct LCT{
 18     intr tree[N];
 19     int xx;
 20     multiset <int> se[N];
 21     void clean(){ tree[0]=intr(); }
 22     void maintain(int t){
 23         tree[t].max=tree[t].t;
 24         if (se[t].size()) tree[t].max=max(tree[t].max,*se[t].rbegin());
 25         if (tree[t].lc) tree[t].max=max(tree[t].max,tree[tree[t].lc].max);
 26         if (tree[t].rc) tree[t].max=max(tree[t].max,tree[tree[t].rc].max);
 27     }
 28     void left(int t){
 29         int fa=tree[t].fat,r=tree[t].rc;
 30         tree[t].rc=tree[r].lc,tree[tree[r].lc].fat=t;
 31         tree[r].lc=t,tree[t].fat=r;
 32         if (tree[t].root) tree[t].root=0,tree[r].root=1;
 33         else if (tree[fa].lc==t) tree[fa].lc=r;
 34         else tree[fa].rc=r;
 35         tree[r].fat=fa;
 36         clean();
 37         maintain(t);
 38         maintain(r);
 39     }
 40     void right(int t){
 41         int fa=tree[t].fat,l=tree[t].lc;
 42         tree[t].lc=tree[l].rc,tree[tree[l].rc].fat=t;
 43         tree[l].rc=t,tree[t].fat=l;
 44         if (tree[t].root) tree[t].root=0,tree[l].root=1;
 45         else if (tree[fa].lc==t) tree[fa].lc=l;
 46         else tree[fa].rc=l;
 47         tree[l].fat=fa;
 48         clean();
 49         maintain(t);
 50         maintain(l);
 51     }
 52     void splay(int t){
 53         while (!tree[t].root){
 54             int fa=tree[t].fat,gr=tree[fa].fat;
 55             if (tree[fa].root){
 56                 if (tree[fa].lc==t) right(fa);
 57                 else left(fa);
 58             }else if (tree[gr].lc==fa){
 59                 if (tree[fa].lc==t) right(gr),right(fa);
 60                 else left(fa),right(gr);
 61             }else if (tree[fa].rc==t) left(gr),left(fa);
 62             else right(fa),left(gr);
 63         }
 64     }
 65     
 66     void access(int t){
 67         xx=1;
 68         for (int x=0,y=t;y;x=y,y=tree[y].fat){
 69         //Wa: no(x=y)    y=fat[y];
 70             splay(y);
 71             if (x) se[y].erase(tree[x].max);
 72             if (tree[y].rc) se[y].insert(tree[tree[y].rc].max);
 73             tree[x].root=0;
 74             tree[tree[y].rc].root=1;
 75             // no (tree[tree[y].rc].root=1;)
 76             tree[y].rc=x;
 77             clean();
 78             maintain(y);
 79         }
 80     }
 81     int getl(int t){
 82         while (tree[t].lc) t=tree[t].lc;
 83         return t;
 84     }
 85     int getans(int t){
 86         access(t);
 87         splay(t);
 88         int root=getl(t);
 89         splay(root);
 90         return col[root]==col[t] ? tree[root].max : tree[tree[root].rc].max;
 91         //                      wa:tree[t].max
 92     }
 93     void changenum(int t,int s){
 94         access(t);
 95         splay(t);
 96         tree[t].t=s;
 97         maintain(t);
 98     }
 99     void cut(int t){
100         access(t);
101         splay(t);
102         tree[tree[t].lc].fat=0;
103         tree[tree[t].lc].root=1;
104         tree[t].lc=0;
105         maintain(t);
106     }
107     void link(int x,int y){
108         splay(x);
109         access(y);
110         splay(y);
111         tree[x].fat=y;
112         se[y].insert(tree[x].max);
113         maintain(y);
114     }
115 }lct[2];
116 void dfs(int t){
117     if (fat[t]) lct[col[t]].tree[t].fat=fat[t];
118     for (int i=son[t];i;i=line[i].next)
119     if (line[i].data!=fat[t]){
120         int ne=line[i].data;
121         fat[ne]=t;
122         dfs(ne);
123         lct[col[ne]].se[t].insert(lct[col[ne]].tree[ne].max);
124     }
125     lct[0].maintain(t);
126     lct[1].maintain(t);
127 }
128 void changecol(int t){
129     if (fat[t]){
130         lct[col[t]].cut(t);
131         lct[col[t]^1].link(t,fat[t]);
132     }
133     col[t]^=1;
134 }
135 int main(){
136     freopen("spoj16580.in","r",stdin);
137     freopen("spoj16580.out","w",stdout);
138     scanf("%d",&n);
139     for (int x,y,i=1;i<n;i++){
140         scanf("%d%d",&x,&y);
141         line[++nl]=inli(son[x],y),son[x]=nl;
142         line[++nl]=inli(son[y],x),son[y]=nl;
143     }
144     for (int i=1;i<=n;i++) scanf("%d",&col[i]);
145     for (int x,i=1;i<=n;i++){
146         scanf("%d",&x);
147         lct[0].tree[i].t=lct[0].tree[i].max=x;
148         lct[1].tree[i].t=lct[1].tree[i].max=x;
149     }
150     dfs(1);
151     scanf("%d",&m);
152     for (int x,y,z,i=1;i<=m;i++){
153         scanf("%d%d",&x,&y);
154         if (i==3)
155         i=3;
156         if (x==0) printf("%d
",lct[col[y]].getans(y));
157         if (x==1) changecol(y);
158         if (x==2){
159             scanf("%d",&z);
160             lct[0].changenum(y,z);
161             lct[1].changenum(y,z);
162         }
163     }
164     fclose(stdin);
165     fclose(stdout);
166 }
View Code
原文地址:https://www.cnblogs.com/g-word/p/3690440.html