题目描述

一棵树上有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]树的统计(树链剖分,线段树)的更多相关文章

  1. BZOJ-1036 树的统计Count 链剖线段树(模板)=(树链剖分+线段树)

    潇爷昨天刚刚讲完...感觉得还可以...对着模板打了个模板...还是不喜欢用指针.... 1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Lim ...

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

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

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

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

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

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

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

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

  6. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  7. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  8. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  9. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  10. 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 ...

随机推荐

  1. GetModuleFileName

    原文:http://www.cnblogs.com/dongzhiquan/archive/2009/07/28/1994776.html GetModuleFileName HMODULE hMod ...

  2. Populating Next Right Pointers in Each Node 设置二叉树的next节点

    Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...

  3. 微信小程序-05-详解介绍.js 逻辑层文件

    上一篇介绍了关于.json 的配置文件,本篇介绍关于.js 逻辑层文件 微信小程序-05-详解介绍.js 逻辑层文件 宝典官方文档: https://developers.weixin.qq.com/ ...

  4. 关闭TCP中135、139、445、593、1025 等端口的操作方法 (转)(记录下)

    操作要领:封闭端口,杜绝网络病毒对这些端口的访问权,以保障计算机安全,减少病毒对上网速度的影响. 近日发现有些人感染了新的网络蠕虫病毒,该病毒使用冲击波病毒专杀工具无法杀除,请各位尽快升级计算机上的杀 ...

  5. leetcode coding base

    1. Contains Duplicate 2. Contains Duplicate II 3. Contains Duplicate III

  6. ext3 转 ext4 操作

    先关闭相关服务 cd / umount /dev/vg_nosql/nosql tune2fs -O has_journal,extents,huge_file,flex_bg,uninit_bg,d ...

  7. 打通版微社区(6):部署微信插件及开通QQ云服务

    写在前面: 此文是我最后写的.其实实际部署的时候,我是先安装了论坛并试图开通微信的微社区.发现微社区需要在微信公众平台的开发者中心里配置 "网页账号,网页授权获取用户基本信息"为论 ...

  8. 使用.Net访问Office编程接口(PIA和IA的区别)

    在这篇文章里面,我将向大家介绍如何在.Net中访问Office所公开的编程接口.其实,不管是使用哪种具体的技术来针对Office进行开发(比如VSTO,或者用C#编写一个Office Add-in,或 ...

  9. 深入浅出SharePoint2010——请假系统实战

    一.需求分析文档 二.请假系统无代码解决方案 2.1 数据框架设计 2.2 权限设计 2.3 表单设计 2.4 工作流设计 2.5 门户主页设计 三.请假系统第三方解决方案(Nintex) 四.请假系 ...

  10. August 30th 2017 Week 35th Wednesday

    A lion does not concern himself with the opinion of sheep. 狮子可不会在意绵羊是怎么想的. As a sheep, you must run ...