ZJOI2008]树的统计(树链剖分,线段树)
题目描述
一棵树上有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”的操作,每行输出一个整数表示要求输出的结果
思路:
树剖板子题
将树剖好后跑线段树查询即可
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rii register int i
#define rij register int j
#define int long long
using namespace std;
int n,head[],size[],f[],zs[],bnt;
int top[],nid[],nsd[],cnt,val[];
int nval[],q;
struct ljb{
int to,nxt;
}y[];
struct xds{
int maxn,sum;
}x[];
inline void add(int from,int to)
{
bnt++;
y[bnt].to=to;
y[bnt].nxt=head[from];
head[from]=bnt;
}
void dfs1(int wz,int fa,int sd)
{
f[wz]=fa;
nsd[wz]=sd;
size[wz]=;
int maxn=;
for(rii=head[wz];i!=;i=y[i].nxt)
{
int to=y[i].to;
if(to!=fa)
{
dfs1(to,wz,sd+);
size[wz]+=size[to];
if(size[to]>maxn)
{
zs[wz]=to;
maxn=size[to];
}
}
}
}
void dfs2(int wz,int ntop)
{
cnt++;
nid[wz]=cnt;
nval[cnt]=val[wz];
top[wz]=ntop;
if(zs[wz]==)
{
return;
}
dfs2(zs[wz],ntop);
for(rii=head[wz];i!=;i=y[i].nxt)
{
int to=y[i].to;
if(zs[wz]!=to&&f[wz]!=to)
{
dfs2(to,to);
}
}
}
void build(int l,int r,int bh)
{
if(l==r)
{
x[bh].sum=nval[l];
x[bh].maxn=nval[l];
return;
}
int mid=(l+r)/;
build(l,mid,bh*);
build(mid+,r,bh*+);
x[bh].sum=x[bh*].sum+x[bh*+].sum;
x[bh].maxn=max(x[bh*].maxn,x[bh*+].maxn);
}
void change(int wz,int nl,int nr,int val,int bh)
{
if(nl==nr&&nl==wz)
{
x[bh].maxn=val;
x[bh].sum=val;
return;
}
int mid=(nl+nr)/;
if(wz<=mid)
{
change(wz,nl,mid,val,bh*);
}
else
{
change(wz,mid+,nr,val,bh*+);
}
x[bh].maxn=max(x[bh*].maxn,x[bh*+].maxn);
x[bh].sum=x[bh*].sum+x[bh*+].sum;
}
int querym(int l,int r,int nl,int nr,int bh)
{
if(l<nl)
{
l=nl;
}
if(r>nr)
{
r=nr;
}
if(l==nl&&r==nr)
{
return x[bh].maxn;
}
int mid=(nl+nr)/;
int val=-;
if(l<=mid)
{
int a1=querym(l,r,nl,mid,bh*);
val=max(a1,val);
}
if(r>mid)
{
int a2=querym(l,r,mid+,nr,bh*+);
val=max(val,a2);
}
return val;
}
int qmax(int from,int to)
{
int ans=-;
while(top[from]!=top[to])
{
if(nsd[top[from]]<nsd[top[to]])
{
swap(from,to);
}
int res=;
res=querym(nid[top[from]],nid[from],,n,);
ans=max(ans,res);
from=f[top[from]];
}
if(nsd[from]>nsd[to])
{
swap(from,to);
}
int res=;
res=querym(nid[from],nid[to],,n,);
ans=max(ans,res);
return ans;
}
int querys(int l,int r,int nl,int nr,int bh)
{
if(l<nl)
{
l=nl;
}
if(r>nr)
{
r=nr;
}
if(l==nl&&r==nr)
{
return x[bh].sum;
}
int mid=(nl+nr)/;
int val=;
if(l<=mid)
{
val+=querys(l,r,nl,mid,bh*);
}
if(r>mid)
{
val+=querys(l,r,mid+,nr,bh*+);
}
return val;
}
int qsum(int from,int to)
{
int ans=;
while(top[from]!=top[to])
{
if(nsd[top[from]]<nsd[top[to]])
{
swap(from,to);
}
int res=;
res=querys(nid[top[from]],nid[from],,n,);
ans+=res;
from=f[top[from]];
}
if(nsd[from]>nsd[to])
{
swap(from,to);
}
int res=;
res=querys(nid[from],nid[to],,n,);
ans+=res;
return ans;
}
signed main()
{
for(rii=;i<=;i++)
{
x[i].maxn=-;
}
scanf("%lld",&n);
for(rii=;i<=n-;i++)
{
int from,to;
scanf("%lld%lld",&from,&to);
add(from,to);
add(to,from);
}
dfs1(,,);
for(rii=;i<=n;i++)
{
scanf("%lld",&val[i]);
}
dfs2(,);
build(,n,);
scanf("%lld",&q);
for(rii=;i<=q;i++)
{
int from,to,val;
string s;
char c=getchar();
while(c<'A'||c>'Z')
{
c=getchar();
}
while(c>='A'&&c<='Z')
{
s+=c;
c=getchar();
}
if(s=="CHANGE")
{
scanf("%lld%lld",&from,&val);
change(nid[from],,n,val,);
}
if(s=="QMAX")
{
scanf("%lld%lld",&from,&to);
int ltt=qmax(from,to);
printf("%lld\n",ltt);
}
if(s=="QSUM")
{
scanf("%lld%lld",&from,&to);
int ltt=qsum(from,to);
printf("%lld\n",ltt);
}
}
}
ZJOI2008]树的统计(树链剖分,线段树)的更多相关文章
- BZOJ-1036 树的统计Count 链剖线段树(模板)=(树链剖分+线段树)
潇爷昨天刚刚讲完...感觉得还可以...对着模板打了个模板...还是不喜欢用指针.... 1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Lim ...
- BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)
BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...
- 【bzoj1036】树的统计[ZJOI2008]树链剖分+线段树
题目传送门:1036: [ZJOI2008]树的统计Count 这道题是我第一次打树剖的板子,虽然代码有点长,但是“打起来很爽”,而且整道题只花了不到1.5h+,还是一遍过样例!一次提交AC!(难道前 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
随机推荐
- Android 一种非常好用的Android屏幕适配
前言 网上关于屏幕适配的文章已经铺天盖地了,为什么我还要讲?因为网上现在基本都是使用px适配,即每种屏幕分辨率的设备需要定义一套dimens.xml文件.再加上有些手机还有虚拟按键(例如华为),这样就 ...
- JAVA中获取文件的大小和文件的扩展名
一.获取文件扩展名(该段代码来自博客园网站装男人的博客https://www.cnblogs.com/nanrenzhuang/archive/2013/05/19/6315546.html) pub ...
- jquery-animate()动画
一.animate()语法 $(“选择器”).animate({CSS样式},时间,运动方式,回调函数); 参数说明: 参数1:CSS属性名,属性值,JSON格式{"属性名":&q ...
- 对数损失函数(Logarithmic Loss Function)的原理和 Python 实现
原理 对数损失, 即对数似然损失(Log-likelihood Loss), 也称逻辑斯谛回归损失(Logistic Loss)或交叉熵损失(cross-entropy Loss), 是在概率估计上定 ...
- 一个java内存泄漏的排查案例
这是个比较典型的java内存使用问题,定位过程也比较直接,但对新人还是有点参考价值的,所以就纪录了一下. 下面介绍一下在不了解系统代码的情况下,如何一步步分析和定位到具体代码的排查过程 (以便新人参考 ...
- Python logger模块
1 logging模块简介 logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级.日志保存路径.日志文件回滚等:相比print,具备如下优点: 可以通过设置不同 ...
- HBuilder:一个不错的web前端IDE(代码编辑器)
Web前端开发,2000之后基本就是三剑客的天下.到现在DW也是不错的HTMLcoder,如今的前端开发早已是JS的天下.但是DW对于JS方面就弱爆了.DW虽然支持JS语法高亮也支持JQuery Jq ...
- [翻译] JSAnimatedImagesView
JSAnimatedImagesView 本人测试的效果: Description:描述 Easy to use UIView subclass to quickly add a cool anima ...
- 测试你的 In-app Billing 程序
测试你的 In-app Billing 程序 为了保证 In-app Billing 可以在你程序中正常使用,你应该在把应用程序发布到Google Play之前进行测试.早期的测试有助于确保用户对于你 ...
- MFC连接Mysql数据库执行查询和插入
配置环境: include:mysql.h文件 lib:libmysql.lib文件 dll::libmysql.dll文件 连接代码: MYSQL m_sqlCon; MYSQL_RES *m_re ...