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",&n);

 94         int x,y,z;

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

 96             scanf("%d%d%d\n",&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\n",&x,&y);

117                 printf("%d\n",getans(x,y));

118             }

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

120                 scanf("%d%d\n",&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",&n);

 75         clean();

 76         int x,y,z;

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

 78             scanf("%d%d%d\n",&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\n",&x,&y);

 87                 printf("%d\n",getdis(x,y));

 88             }

 89             if (s[0]=='K'){

 90                 scanf("%d%d%d\n",&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\n",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\n",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\n",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

 

 

 

你可能感兴趣的:(tree)