洛谷——P2590 [ZJOI2008]树的统计
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”的操作,每行输出一个整数表示要求输出的结果。
输入输出样例
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
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]树的统计的更多相关文章
- 洛谷——P2590 [ZJOI2008]树的统计(树链剖分模板练手)
P2590 [ZJOI2008]树的统计 I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问 ...
- 洛谷P2590 [ZJOI2008] 树的统计 [树链剖分]
题目传送门 树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t ...
- 洛谷P2590 [ZJOI2008]树的统计 题解 树链剖分+线段树
题目链接:https://www.luogu.org/problem/P2590 树链剖分模板题. 剖分过程要用到如下7个值: fa[u]:u的父节点编号: dep[u]:u的深度: size[u]: ...
- 洛谷 P2590 [ZJOI2008]树的统计(树链剖分)
题目描述一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v ...
- 洛谷 P2590 [ZJOI2008]树的统计
大家好,我非常喜欢暴力数据结构,于是我用块状树过了这道题目 题目: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE ...
- [洛谷P2590][ZJOI2008]树的统计
题目大意:一棵树,支持三个操作, $CHANGE\;u\;t:$ 把结点$u$的权值改为$t$ $QMAX\;u\;v:$ 询问从点$u$到点$v$的路径上的节点的最大权值 $QSUM\;u\;v:$ ...
- 洛谷.2590.[ZJOI2008]树的统计(树分块)
题目链接 Update:这种分块写法...可以被卡掉啊... 好像没有靠谱的树分块写法... /* 对树上节点进行分块,每个点记录dep,fa,val,Max,Sum,Max,Sum表示当前点在该块内 ...
- P2590 [ZJOI2008]树的统计(树链剖分)
P2590 [ZJOI2008]树的统计 虽然是入门树剖模板 但是我终于1A了(大哭) 懒得写啥了(逃 #include<iostream> #include<cstdio> ...
- P2590 [ZJOI2008]树的统计(LCT)
P2590 [ZJOI2008]树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把 ...
随机推荐
- NPashaP的二分图源码部分
源码链接:https://github.com/nelsonkuang/ant-admin/blob/master/src/utils/d3-viz.js 的二分图部分. 1.整体的级联结构 整个bp ...
- ArcGIS api for javascript——地图配置-增加标注到滑动器
描述 ArcGISTiledMapServiceLayer,这意味着图层有一个在明确的比例的预先渲染的地图切片的cache.能够从tileInfo属性获得图层的的缓存比例数组.这是本例中标注如何被得到 ...
- ios 绘图,绘制坐标系,画坐标系
先来看个效果: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/d ...
- android音乐播放器开发 SweetMusicPlayer 载入歌曲列表
上一篇写了播放器的总体实现思路,http://blog.csdn.net/huweigoodboy/article/details/39855653,如今来总结下载入歌曲列表. 代码地址:https: ...
- 三星N900(note3)刷机包 颓废N0.8.1 修复已知BUG 集成谷歌服务
ROM介绍 8.1更新信息:攻克了来电后点击HOME出现SECPHONE已经停止的问题 去掉了桌面隐藏信息的选项,官方最新底包暂不支持这功能 增加了网友们须要验证的谷歌服务(不须要的同学同步什么的都关 ...
- ORA-12012 Error on auto execute of job "SYS"."ORA$AT_OS_OPT_SY_<NN> in 12.2.0 Database
报错如下:ORA-12012: error on auto execute of job "SYS"."ORA$AT_OS_OPT_SY_88"ORA-2000 ...
- Debian9.5解决在root用户下启用VNC后lightdm+Xfce4只能使用root登录,其他用户无法登陆
Debian9.5解决在root用户下启用VNC后lightdm+Xfce4只能使用root登录,其他用户无法登陆 最近在研究debian9.5 VNC的问题,当VNC使用tightVNC或tiger ...
- QQ空间说说爬虫
QQ空间说说爬虫 闲来无事,写了一个QQ空间的爬虫,主要是爬取以前的说说,然后生成词云. 这次采用的主要模块是selenium,这是一个模拟浏览器的模块,一开始我不想用这个模块写的,但是后面分析的时候 ...
- 紫书 例题 9-2 UVa 437 ( DAG的动态规划)
很明显可以根据放不放建边,然后最一遍最长路即是答案 DAG上的动态规划就是根据题目中的二元关系来建一个 DAG,然后跑一遍最长路和最短路就是答案,可以用记忆化搜索的方式来实现 细节:(1)注意初始化数 ...
- Swift学习笔记(3)--基本运算符
基本运行符: +(加法.正数) - (减法.负数) * (乘法) / (除法) % (求余) : 在Swift中,求余可以是浮点数求余. &&(逻辑与) || (逻辑或) ^ (逻 ...