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 }
  • 相关阅读:
    2. Add Two Numbers
    1. Two Sum
    leetcode 213. 打家劫舍 II JAVA
    leetcode 48. 旋转图像 java
    leetcode 45. 跳跃游戏 II JAVA
    leetcode 42. 接雨水 JAVA
    40. 组合总和 II leetcode JAVA
    24. 两两交换链表中的节点 leetcode
    1002. 查找常用字符 leecode
    leetcode 23. 合并K个排序链表 JAVA
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/5228882.html
Copyright © 2011-2022 走看看