题目描述

一棵树上有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. this keyword details

    学生类: package com.itheima_07; /* * 学生类 * * 起名字我们要求做到见名知意. * 而我们现在的代码中的n和a就没有做到见名知意,所以我要改进. * * 如果有局部变 ...

  2. 已经不再使用的表为什么数据页还在SQLServer的内存缓存中

    1. 问题发现 在学习内存调优时,使用如下代码,查询目前内存缓冲区中生产数据库的每个对象缓存页计数 SELECT count(*)AS cached_pages_count ,name ,index_ ...

  3. SQLServer2008或SQLServer2008 R2没有智能提示解决方法

    如果没有智能提示,需要安装SqlcompletefreeSQL Server智能提示

  4. 我的JS历史知识

    话说在那long long ago的1995以前,绝大多数因特网用户都使用速度仅28.8kbit/s的猫(调制调解器)上网,人们注册成为某个网站的用户时,填写好资料,发送给服务器去验证,如果某一资料填 ...

  5. Vscode rg.exe cpu 占用过高

    文件-> 首选项 -> 设置 -> 搜索search.followSymlinks 或者 修改settings.json 添加 "search.followSymlinks ...

  6. 外部主机无法访问IIS发布的网站

    在IIS中发布网站,在本地可以直接访问,但是其他主机不能访问改发布的网站.   此问题一般是IIS的配置或者防火墙的配置的原因.     如果禁用了以下防火墙入站规则会导致外部主机无法访问本地发布的网 ...

  7. laravel controller重写

    <?php namespace Boss\Http\Controllers; use Illuminate\Foundation\Bus\DispatchesJobs; use Illumina ...

  8. node升级 npm的升级

    安装方法: 1.产看node版本,没安装的请先安装: node -v 2.清楚node缓存: sudo npm cache clean -f 3.安装node版本管理工具'n'; sudo npm i ...

  9. BT提权wind2008R2

    昨天中午打开电脑,对着菜刀在那翻啊翻,找到一个64bit的os. 因为这个ip不在曾经提权过的主机列表里面,心想这应该是个低权限的网站,顺手打个whoami试试,结果给我返回了"nt aut ...

  10. vs中添加工具cmder并自动定位到当前目录

    有时在vs中为了使用git命令行,需要打开cmder工具,并让cmder自切换到当前目录: 方法1: 看下效果: 方法2:在文件夹中右键(添加到右键自行百度)