zoukankan      html  css  js  c++  java
  • bzoj3639: Query on a tree VII

    Description

    You are given a tree (an acyclic undirected connected graph) with n nodes. The tree nodes are numbered from 1 to n.

    Each node has a color, white or black, and a weight.

    We will ask you to perfrom some instructions of the following form:

    • u : ask for the maximum weight among the nodes which are connected to u, two nodes are connected iff all the node on the path from u to v (inclusive u and v) have a same color.
    • u : toggle the color of u(that is, from black to white, or from white to black).
    • u w: change the weight of u to w.
     

    Input

    The first line contains a number n denoted how many nodes in the tree(1 ≤ n ≤ 105). The next n - 1 lines, each line has two numbers (u,  v) describe a edge of the tree(1 ≤ u,  v ≤ n).

    The next 2 lines, each line contains n number, the first line is the initial color of each node(0 or 1), and the second line is the initial weight, let's say Wi, of each node(|Wi| ≤ 109).

    The next line contains a number m denoted how many operations we are going to process(1 ≤ m ≤ 105). The next m lines, each line describe a operation (t,  u) as we mentioned above(0 ≤ t ≤ 2, 1 ≤ u ≤ n|w| ≤ 109).

     

    Output

    For each query operation, output the corresponding result.

     

    Sample Input

    5
    1 2
    1 3
    1 4
    1 5
    0 1 1 1 1
    1 2 3 4 5
    3
    0 1
    1 1
    0 1

    Sample Output

    1
    5
     
    题解:
    http://www.cnblogs.com/chenyushuo/p/5228875.html 这个相似,不过要用set维护通过虚边相连的点的最大权值,lct维护这条链上的最大值。
    code:
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<set>
     7 using namespace std;
     8 char ch;
     9 bool ok;
    10 void read(int &x){
    11     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    12     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    13     if (ok) x=-x;
    14 }
    15 const int maxn=100005;
    16 const int maxm=200005;
    17 int n,q,op,a,b,v,tot,now[maxn],son[maxm],pre[maxm],fa[maxn],col[maxn];
    18 struct lct{
    19     int id,fa[maxn],son[maxn][2],val[maxn],maxv[maxn];
    20     multiset<int> rest[maxn];
    21     int which(int x){return son[fa[x]][1]==x;}
    22     bool isroot(int x){return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;}
    23     void update(int x){
    24         maxv[x]=val[x];
    25         if (!rest[x].empty()) maxv[x]=max(maxv[x],*rest[x].rbegin());
    26         if (son[x][0]) maxv[x]=max(maxv[x],maxv[son[x][0]]);
    27         if (son[x][1]) maxv[x]=max(maxv[x],maxv[son[x][1]]);
    28     }
    29     void rotate(int x){
    30         int y=fa[x],z=fa[y],d=which(x),dd=which(y);
    31         fa[son[x][d^1]]=y,son[y][d]=son[x][d^1],fa[x]=fa[y];
    32         if (!isroot(y)) son[z][dd]=x;
    33         fa[y]=x,son[x][d^1]=y,update(y),update(x);
    34     }
    35     void splay(int x){
    36         while (!isroot(x)){
    37             if (isroot(fa[x])) rotate(x);
    38             else if (which(x)==which(fa[x])) rotate(fa[x]),rotate(x);
    39             else rotate(x),rotate(x);
    40         }
    41     }
    42     void access(int x){
    43         for (int p=0;x;x=fa[x]){
    44             splay(x);
    45             if (son[x][1]) rest[x].insert(maxv[son[x][1]]);
    46             if (p) rest[x].erase(rest[x].find(maxv[p]));
    47             son[x][1]=p,update(p=x);
    48         }
    49     }
    50     void link(int x,int y){
    51         if (!y) return;
    52         access(y),splay(y),splay(x),fa[x]=y,son[y][1]=x,update(y);
    53     }
    54     void cut(int x,int y){
    55         if (!y) return;
    56         access(x),splay(x),fa[son[x][0]]=0,son[x][0]=0,update(x);
    57     }
    58     int find_root(int x){for (access(x),splay(x);son[x][0];x=son[x][0]); return x;}
    59     void query(int x){
    60         int t=find_root(x); splay(t);
    61         printf("%d
    ",col[t]==id?maxv[t]:maxv[son[t][1]]);
    62     }
    63     void modify(int x,int v){access(x),splay(x),val[x]=v,update(x);}
    64 }T[2];
    65 void put(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;}
    66 void add(int a,int b){put(a,b),put(b,a);}
    67 void dfs(int u){
    68     for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
    69         if (v!=fa[u]) fa[v]=u,T[col[v]].link(v,u),dfs(v);
    70 }
    71 int main(){
    72     read(n),T[0].id=0,T[1].id=1;
    73     for (int i=1;i<n;i++) read(a),read(b),add(a,b);
    74     for (int i=1;i<=n;i++) read(col[i]);
    75     for (int i=1;i<=n;i++) read(T[0].val[i]),T[0].maxv[i]=T[0].val[i];
    76     for (int i=1;i<=n;i++) T[1].maxv[i]=T[1].val[i]=T[0].val[i];
    77     dfs(1);
    78     for (read(q);q;q--){
    79         read(op),read(a);
    80         if (op==0) T[col[a]].query(a);
    81         else if (op==1) T[col[a]].cut(a,fa[a]),col[a]^=1,T[col[a]].link(a,fa[a]);
    82         else read(v),T[0].modify(a,v),T[1].modify(a,v);
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    完整的网站开发技术学习建议
    在微信小程序中绘制图表(part2)
    原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
    第八届蓝桥杯第二题:等差素数列
    第七届蓝桥杯第四题:快速排序
    51Nod:1086背包问题 V2
    POJ:2386 Lake Counting(dfs)
    51Nod:1268 和为K的组合
    迭代器
    51Nod:1134 最长递增子序列
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/5228882.html
Copyright © 2011-2022 走看看