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 ...
随机推荐
- Grunt入门学习之(1) -- 环境安装
Grunt入门学习(1) - 环境安装 这周根据项目需要,在项目的基础上分模块开发了一个小的项目板块,但是在规范组织每个模块的代码和其依赖性时比较麻烦,需要一个项目板块的构建工具.各个模块都包括其对应 ...
- 实验吧Crypto题目Writeup
这大概是一篇不怎么更新的没什么用的网上已经有了很多差不多的东西的博客. 变异凯撒 忘记了2333 传统知识+古典密码 先查百度百科,把年份变成数字,然后猜测+甲子的意思,一开始以为是加1,后来意识到是 ...
- [2014年学习计划之RoR系列] 第二步 – 熟悉Ruby语言 (2/n) Blocks and Iterators (代码块和迭代器)
[就算没有含金量,也请尊重原创, 转载自我的独立博客http://brucejia.net] Blocks and Iterators (代码块和迭代器) 代码块和迭代器是Ruby语言中比较有特点的东 ...
- Mac系统查看端口占用和杀死进程
查看进程占用 lsof -i tcp:8080 该命令会显示占用8080端口的进程,有其 pid ,可以通过pid关掉该进程 杀死进程 kill pid 例如 kill 39394 转自:https: ...
- npdp
我报名比较晚,等缴费最后期限,才缴费,下定决心,开始正式的备考. 我的工作比较忙,备考时间特比较短,从拿到书到考试只有一个月了,心理慌慌的. 在岳老师的帮助下,完成了报名资格申请.拿到备考计划,就赶紧 ...
- jsonp和ajax的区别
一.Ajax工作原理 相当于在用户和服务器之间加了—个中间层(AJAX引擎),使用户操作与服务器响应异步化.对于用户请求ajax引擎会做一些数据验证和数据处理,不是所有请求都提交给服务器,当需要从服务 ...
- 一、python小功能记录——监听键盘事件
1.监听键盘按键 from pynput.keyboard import Listener def press(key): print(key.char) with Listener(on_press ...
- Facebook POP 使用指南
Facebook POP 使用指南 Pop是一个动画引擎,用以扩展iOS.OSX的动画类型.相较于iOS.OSX中的基本动画效果,Pop扩展后支持弹簧动画效果与衰减动画效果,你可以用Pop动画引擎来构 ...
- CAGradientLayer实现图片渐变透明效果
CAGradientLayer实现图片渐变透明效果 要实现的效果如下: 源码: // // RootViewController.m // CAGradientLayer // // Copyrigh ...
- 关于$.fn.scrollPath is not a function
关于$.fn.scrollPath is not a function 在做项目过程中,用到了一个jQuery的滚动路径插件——jQuery Scroll Path.引入相关的js文件后,但是控制台一 ...