• 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
  • 相关阅读:
    网络七层
    微信小程序开发工具 常用快捷键
    BZOJ 1026 windy数 (数位DP)
    BZOJ 1026 windy数 (数位DP)
    CodeForces 55D Beautiful numbers (SPOJ JZPEXT 数位DP)
    CodeForces 55D Beautiful numbers (SPOJ JZPEXT 数位DP)
    HDU 3709 Balanced Number (数位DP)
    HDU 3709 Balanced Number (数位DP)
    UVA 11361 Investigating Div-Sum Property (数位DP)
    UVA 11361 Investigating Div-Sum Property (数位DP)
  • 原文地址:https://www.cnblogs.com/g-word/p/3690440.html
Copyright © 2020-2023  润新知