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\n",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 }
时间: 2024-10-14 23:02:37

bzoj3639: Query on a tree VII的相关文章

BZOJ 3639: Query on a tree VII

Description 一棵树,支持三种操作,修改点权,修改颜色,问所有与他路径上颜色相同的点的最大权,包含这两个点. Sol LCT. 用LCT来维护重边,对于每个节点在建一个set用来维护轻边,这样Link和Cut是时候就非常好操作了,直接Access一下,Splay一下,直接删掉就可以了. 因为set是不统计重边的,然后对于每个节点的信息由他的父亲来保存,因为一个节点可能有很多儿子但一定只有一个父亲. 还有一个问题就是每个点的权值不能建全局的,因为维护的两颗LCT不能够同时删除,所以每个L

SP16580 QTREE7 - Query on a tree VII

Description 一棵树,每个点初始有个点权和颜色(0/1) 0 u :询问所有u,v 路径上的最大点权,要满足u,v 路径上所有点的颜色都相同 1 u :反转u 的颜色 2 u w :把u 的点权改成w Solution 对于每一种颜色,我们开一个 \(LCT\) 来维护 首先为了使得 \(LCT\) 维护的黑树连通,难免会有白点,但是最多只会有一个,因为一旦不连通了就没有必要维护了,对于白树也是同理 对于每一个 \(LCT\) 的节点,只需要维护一个 \(splay\) 中的子树 \(

spoj 375 Query on a tree (树链剖分)

Query on a tree You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. We will ask you to perfrom some instructions of the following form: CHANGE i ti : change the cost of the i-th edge to ti or Q

【百度之星2014~复赛)解题报告】The Query on the Tree

声明 笔者最近意外的发现 笔者的个人网站http://tiankonguse.com/ 的很多文章被其它网站转载,但是转载时未声明文章来源或参考自 http://tiankonguse.com/ 网站,因此,笔者添加此条声明. 郑重声明:这篇记录<[百度之星2014~复赛)解题报告]The Query on the Tree>转载自 http://tiankonguse.com/ 的这条记录:http://tiankonguse.com/record/record.php?id=673 前言

[hdu 6191] Query on A Tree

Query on A Tree Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 733    Accepted Submission(s): 275 Problem Description Monkey A lives on a tree, he always plays on this tree. One day, monkey

QTREE - Query on a tree

QTREE - Query on a tree 题目链接:http://www.spoj.com/problems/QTREE/ 参考博客:http://blog.sina.com.cn/s/blog_7a1746820100wp67.html 树链剖分入门题 代码如下(附注解): 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define lson (x<<1) 5 #d

SPOJ375 Query on a tree 树链剖分

SPOJ375  Query on a tree   树链剖分 no tags You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. We will ask you to perfrom some instructions of the following form: CHANGE i ti : change the cost of

HDU 4836 The Query on the Tree lca || 欧拉序列 || 动态树

lca的做法还是很明显的,简单粗暴, 不过不是正解,如果树是长链就会跪,直接变成O(n).. 最后跑的也挺快,出题人还是挺阳光的.. 动态树的解法也是听别人说能ac的,估计就是放在splay上剖分一下,做法还是比较复杂的,,, 来一发lca: #include <stdio.h> #include <iostream> #include <algorithm> #include <sstream> #include <stdlib.h> #inc

SPOJ QTREE 375. Query on a tree

SPOJ Problem Set (classical) 375. Query on a tree Problem code: QTREE You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. We will ask you to perfrom some instructions of the following form: CHA