https://www.luogu.org/problem/show?pid=2590#sub

题目描述

一棵树上有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本身

输入输出格式

输入格式:

输入文件的第一行为一个整数n,表示节点的个数。

接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。

接下来一行n个整数,第i个整数wi表示节点i的权值。

接下来1行,为一个整数q,表示操作的总数。

接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。

输出格式:

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

输入输出样例

输入样例#1:

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
输出样例#1:

4
1
2
2
10
6
5
6
5
16

说明

对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

树剖模板

 #include <algorithm>
#include <string>
#include <cstdio> using namespace std; const int N(+);
int n,u,v,val[N],q;
char op[]; int head[N],sumedge;
struct Edge
{
int u,v,next;
Edge(int u=,int v=,int next=):
u(u),v(v),next(next){}
}edge[N<<];
void ins(int u,int v)
{
edge[++sumedge]=Edge(u,v,head[u]);
head[u]=sumedge;
} int cnt,id[N],dfn[N],size[N],son[N],top[N],dad[N],deep[N];
void DFS(int u,int father,int deepth)
{
deep[u]=deepth;
dad[u]=father;
size[u]=;
son[u]=;
for(int i=head[u];i;i=edge[i].next)
{
int to=edge[i].v;
if(dad[u]==to) continue;
DFS(to,u,deepth+); size[u]+=size[to];
if(!son[u]||size[son[u]]<size[to]) son[u]=to;
}
}
void DFS_(int u,int Top)
{
top[u]=Top;
id[u]=++cnt;
dfn[cnt]=u;
if(son[u]) DFS_(son[u],Top);
for(int i=head[u];i;i=edge[i].next)
{
int to=edge[i].v;
if(to!=dad[u]&&to!=son[u]) DFS_(to,to);
}
} struct Tree
{
int l,r,mid,sumval,maxval;
}tree[N<<];
void Tree_up(int now)
{
tree[now].sumval=tree[now<<].sumval+tree[now<<|].sumval;
tree[now].maxval=max(tree[now<<].maxval,tree[now<<|].maxval);
}
void Tree_build(int now,int l,int r)
{
tree[now].l=l;tree[now].r=r;
if(l==r)
{
tree[now].maxval=val[dfn[l]];
tree[now].sumval=val[dfn[l]];
return ;
}
tree[now].mid=l+r>>;
Tree_build(now<<,l,tree[now].mid);
Tree_build(now<<|,tree[now].mid+,r);
Tree_up(now);
}
void Tree_change(int now,int to,int x)
{
if(tree[now].l==tree[now].r)
{
tree[now].maxval=x;
tree[now].sumval=x;
return ;
}
if(tree[now].mid>=to) Tree_change(now<<,to,x);
else if(tree[now].mid<to) Tree_change(now<<|,to,x);
Tree_up(now);
}
int Tree_querymax(int now,int l,int r)
{
if(tree[now].l==l&&tree[now].r==r) return tree[now].maxval;
if(tree[now].mid>=r) return Tree_querymax(now<<,l,r);
else if(tree[now].mid<l) return Tree_querymax(now<<|,l,r);
else return max(Tree_querymax(now<<,l,tree[now].mid),Tree_querymax(now<<|,tree[now].mid+,r));
}
int Tree_querysum(int now,int l,int r)
{
if(tree[now].l==l&&tree[now].r==r) return tree[now].sumval;
if(tree[now].mid>=r) return Tree_querysum(now<<,l,r);
else if(tree[now].mid<l) return Tree_querysum(now<<|,l,r);
else return Tree_querysum(now<<,l,tree[now].mid)+Tree_querysum(now<<|,tree[now].mid+,r);
} int List_querymax(int x,int y)
{
int ret=-1e9;
for(;top[x]!=top[y];x=dad[top[x]])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
ret=max(ret,Tree_querymax(,id[top[x]],id[x]));
}
if(id[x]>id[y]) swap(x,y);
ret=max(ret,Tree_querymax(,id[x],id[y]));
return ret;
}
int List_querysum(int x,int y)
{
int ret=;
for(;top[x]!=top[y];x=dad[top[x]])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
ret+=Tree_querysum(,id[top[x]],id[x]);
}
if(id[x]>id[y]) swap(x,y);
ret+=Tree_querysum(,id[x],id[y]);
return ret;
} int main()
{
scanf("%d",&n);
for(int i=;i<n;i++)
scanf("%d%d",&u,&v),ins(u,v),ins(v,u);
for(int i=;i<=n;i++) scanf("%d",val+i);
DFS(,,);DFS_(,);
Tree_build(,,n);
scanf("%d",&q);
for(;q--;)
{
scanf("%s%d%d",op,&u,&v);
if(op[]=='C') Tree_change(,id[u],v);
else if(op[]=='M') printf("%d\n",List_querymax(u,v));
else printf("%d\n",List_querysum(u,v));
}
return ;
}

洛谷——P2590 [ZJOI2008]树的统计的更多相关文章

  1. 洛谷——P2590 [ZJOI2008]树的统计(树链剖分模板练手)

    P2590 [ZJOI2008]树的统计 I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问 ...

  2. 洛谷P2590 [ZJOI2008] 树的统计 [树链剖分]

    题目传送门 树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t ...

  3. 洛谷P2590 [ZJOI2008]树的统计 题解 树链剖分+线段树

    题目链接:https://www.luogu.org/problem/P2590 树链剖分模板题. 剖分过程要用到如下7个值: fa[u]:u的父节点编号: dep[u]:u的深度: size[u]: ...

  4. 洛谷 P2590 [ZJOI2008]树的统计(树链剖分)

    题目描述一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v ...

  5. 洛谷 P2590 [ZJOI2008]树的统计

    大家好,我非常喜欢暴力数据结构,于是我用块状树过了这道题目 题目: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE ...

  6. [洛谷P2590][ZJOI2008]树的统计

    题目大意:一棵树,支持三个操作, $CHANGE\;u\;t:$ 把结点$u$的权值改为$t$ $QMAX\;u\;v:$ 询问从点$u$到点$v$的路径上的节点的最大权值 $QSUM\;u\;v:$ ...

  7. 洛谷.2590.[ZJOI2008]树的统计(树分块)

    题目链接 Update:这种分块写法...可以被卡掉啊... 好像没有靠谱的树分块写法... /* 对树上节点进行分块,每个点记录dep,fa,val,Max,Sum,Max,Sum表示当前点在该块内 ...

  8. P2590 [ZJOI2008]树的统计(树链剖分)

    P2590 [ZJOI2008]树的统计 虽然是入门树剖模板 但是我终于1A了(大哭) 懒得写啥了(逃 #include<iostream> #include<cstdio> ...

  9. P2590 [ZJOI2008]树的统计(LCT)

    P2590 [ZJOI2008]树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把 ...

随机推荐

  1. 关于thinkphp 命令行

    很多人做多年开发只懂得PHP能在浏览器下运行或者只能结合APACHE等WEB服务器运行,却不晓得,PHP也能用命令行执行,或许是由于大多人在WINDOWS平台做开发部署运行,比较少接触LINUX. T ...

  2. laravel中soapServer支持wsdl的例子

    最近在对接客户的CRM系统,获取令牌时,要用DES方式加密解密,由于之前没有搞错这种加密方式,经过请教了"百度"和"谷歌"两个老师后,结合了多篇文档内容后,终于 ...

  3. UML 绘图关系

    1 继承         子类继承父类   2 实现         实现类实现接口 3 依赖 (偶然.临时.比较弱关联)     类 A 使用了类 B,如果类 B 产生变化将会影响类A       ...

  4. Log4j2打印一行日志时返回本行日志的字符串

    import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.impl.Log4jLogEvent; impo ...

  5. 基于请求响应的MVC框架调用分析

    一.使用Servlet来处理请求响应 当client提交数据之后.接着发送请求,请求被封装成对象,server接收到请求,依据请求的URL.来推断将请求对象交由哪个Servlet处理. 在servle ...

  6. 鸟哥的Linux私房菜-----15、例行性命令at与crontab

  7. Oracle数据库备份恢复,巡检须要关注的对象设置以及相关恢复概述

    数据库备份恢复.巡检须要关注的对象设置: 1.数据库名称,以及DBID:  --dbid在v$database中     SYS@ORCL>select dbid,name from v$dat ...

  8. 如何调试Blink?

    内容 尽管有很多工具和技巧可用于调试Blink,这个文章的重点调试Blink除布局測试之外的feature. 1 介绍 2 Linux 2.1 入门 2.2 启动Debugger 3 实用的工具 3. ...

  9. Create the Project

    https://docs.microsoft.com/en-us/aspnet/web-forms/overview/getting-started/getting-started-with-aspn ...

  10. Mybatis传多个参数(推荐)

    Dao层的函数方法 int deleteMsgById(@Param("name") String name,@Param("id") String id); ...