1036: [ZJOI2008]树的统计Count

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 10677  Solved: 4313
[Submit][Status][Discuss]

Description


棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t :
把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v:
询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身

Input


入的第一行为一个整数n,表示节点的个数。接下来n –
1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数
q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到
30000之间。

Output

对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

Sample Input

4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4

Sample Output

4
1
2
2
10
6
5
6
5
16

【思路】

树链剖分,线段树

线段树:区间查询max sum ,单点操作 set。

注意一下负数就行了=-=。

【代码】

 #include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; const int N = +;
const int INF = 1e9; struct Node {
int mx,sum;
Node() {mx=-INF,sum=;}
}T[N<<]; int n,q,z;
char s[];
vector<int> g[N];
//INIT
int top[N],son[N],dep[N],fa[N],siz[N],w[N];
void dfs1(int u) {
son[u]=; siz[u]=;
for(int i=;i<g[u].size();i++) {
int v=g[u][i];
if(v!=fa[u]) {
fa[v]=u , dep[v]=dep[u]+;
dfs1(v);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]]) son[u]=v;
}
}
}
void dfs2(int u,int tp) {
top[u]=tp; w[u]=++z;
if(son[u]) dfs2(son[u],tp);
for(int i=;i<g[u].size();i++) {
int v=g[u][i];
if(v!=fa[u] && v!=son[u]) dfs2(v,v);
}
}
//SEGMENT TREE
void update(int u,int L,int R,int r,int x) {
if(L==R) T[u].mx=T[u].sum=x;
else {
int M=(L+R)>>,lc=u<<,rc=lc|;
if(r<=M) update(lc,L,M,r,x);
else update(rc,M+,R,r,x);
T[u].mx=max(T[lc].mx,T[rc].mx);
T[u].sum=T[lc].sum+T[rc].sum;
}
}
int qsum,qmx;
void query(int u,int L,int R,int l,int r) {
if(l<=L && R<=r)
qsum+=T[u].sum , qmx=max(qmx,T[u].mx);
else {
int M=(L+R)>>;
if(l<=M) query(u<<,L,M,l,r);
if(M<r) query(u<<|,M+,R,l,r);
}
}
//树链剖分
int query(int u,int v,int flag) {
int sum=,mx=-INF;
while(top[u]!=top[v]) {
if(dep[top[u]]<dep[top[v]]) swap(u,v);
qsum= , qmx=-INF;
query(,,z,w[top[u]],w[u]);
sum+=qsum , mx=max(mx,qmx);
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
qsum= , qmx=-INF;
query(,,z,w[u],w[v]);
sum+=qsum , mx=max(mx,qmx);
return flag? sum:mx;
} void read(int& x) {
char c=getchar(); int f=; x=;
while(!isdigit(c)) {if(c=='-')f=-;c=getchar();}
while(isdigit(c)) x=x*+c-'',c=getchar();
x*=f;
}
int main() {
read(n);
int u,v,x;
FOR(i,,n-) {
read(u),read(v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs1(),dfs2(,);
FOR(i,,n)
read(x) , update(,,z,w[i],x);
read(q);
while(q--) {
scanf("%s",s);
read(u),read(v);
if(s[]=='C') update(,,z,w[u],v);
else
if(s[]=='M') printf("%d\n",query(u,v,));
else printf("%d\n",query(u,v,));
}
return ;
}

bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)的更多相关文章

  1. BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)

    BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...

  2. 【bzoj1036】树的统计[ZJOI2008]树链剖分+线段树

    题目传送门:1036: [ZJOI2008]树的统计Count 这道题是我第一次打树剖的板子,虽然代码有点长,但是“打起来很爽”,而且整道题只花了不到1.5h+,还是一遍过样例!一次提交AC!(难道前 ...

  3. BZOJ.1758.[WC2010]重建计划(分数规划 点分治 单调队列/长链剖分 线段树)

    题目链接 BZOJ 洛谷 点分治 单调队列: 二分答案,然后判断是否存在一条长度在\([L,R]\)的路径满足权值和非负.可以点分治. 对于(距当前根节点)深度为\(d\)的一条路径,可以用其它子树深 ...

  4. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

  5. BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)

    前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...

  6. bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2852  Solved: 1668[Submit][Sta ...

  7. bzoj 2157: 旅游【树链剖分+线段树】

    裸的树链剖分+线段树 但是要注意一个地方--我WA了好几次才发现取完相反数之后max值和min值是要交换的-- #include<iostream> #include<cstdio& ...

  8. BZOJ 3589 动态树 (树链剖分+线段树)

    前言 众所周知,90%90\%90%的题目与解法毫无关系. 题意 有一棵有根树,两种操作.一种是子树内每一个点的权值加上一个同一个数,另一种是查询多条路径的并的点权之和. 分析 很容易看出是树链剖分+ ...

  9. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  10. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

随机推荐

  1. Swift小功能点积累

    label字符加删除线 let label = UILabel(frame: CGRectMake(, , , )) let attr = NSMutableAttributedString(&quo ...

  2. 查找PHP的配置文件

    查找PHP的配置文件 先写了一个 <?php phpinfo();?>然后在浏览器中浏览一下(之前我百度说在Configuration File  这个位置看) 结果竟然显示 Loaded ...

  3. webp介绍与使用

        webp是谷歌10年发布的一种新的图片格式,支持有损压缩或无损压缩.据官方称无损压缩的webp在体积上要比png小26%,而有损压缩要比同质量jpg小25%~34%.经本人测试,由腾讯智图处理 ...

  4. WPF 得一些问题汇总

    1.CallMethodAction <TextBox Height="30" Name="txtUserName" Width="160&qu ...

  5. c# 如何通过反射 获取\设置属性值、

    //定义类public class MyClass{public int Property1 { get; set; }}static void Main(){MyClass tmp_Class = ...

  6. C语言中调用Lua

    C语言和Lua天生有两大隔阂: 一.C语言是静态数据类型,Lua是动态数据类型 二.C语言需要程序员管理内存,Lua自动管理内存 为了跨越世俗走到一起,肯定需要解决方案. 解决第一点看上去比较容易,C ...

  7. 使用ajax和history.pushState无刷新改变页面URL onpopstate(转)

    Javascript代码 var htmlData1 = $.ajax(    {    url: "/getXXXResponse",    async: false }).re ...

  8. SVN - 配置

    版本控制器 1.创建文件夹 svn 2.打开终端 进入该文件夹 3.输入 svnadmin 如果有错 xcrun: error: active developer path ("/Appli ...

  9. 从xib加载文件

    一般自定义View, 如果从xib加载文件, 定义一个类方法, 返回xib + (instancetype)dropdown { return [[[NSBundle mainBundle] load ...

  10. 第 12 章 命令模式【Command Pattern】

    以下内容出自:<<24种设计模式介绍与6大设计原则>> 今天讲命令模式,这个模式从名字上看就很简单,命令嘛,老大发命令,小兵执行就是了,确实是这个意思,但是更深化了,用模式来描 ...