【BZOJ】1036 [ZJOI2008]树的统计Count
【算法】树链剖分+线段树
【题解】模板题,见http://www.cnblogs.com/onioncyc/p/6207462.html
调用线段数时要用新编号pos[i] !!!
#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
const int maxn=,inf=0x3f3f3f3f;
int pos[maxn],top[maxn],dfsnum,f[maxn],deep[maxn],size[maxn],first[maxn],n,tot,a[maxn];
struct edge{int u,v,from;}e[maxn*];
struct tree{int l,r,sum,mx;}t[maxn*];
int read()
{
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
void insert(int u,int v)
{tot++;e[tot].u=u;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
void dfs1(int x,int fa)
{
size[x]=;
for(int i=first[x];i;i=e[i].from)
if(e[i].v!=fa)
{
int y=e[i].v;
deep[y]=deep[x]+;
f[y]=x;
dfs1(y,x);
size[x]+=size[y];
}
}
void dfs2(int x,int tp,int fa)
{
int k=;
pos[x]=++dfsnum;
top[x]=tp;
for(int i=first[x];i;i=e[i].from)
if(e[i].v!=fa&&size[e[i].v]>size[k])k=e[i].v;
if(k==)return;
dfs2(k,tp,x);
for(int i=first[x];i;i=e[i].from)
if(e[i].v!=fa&&e[i].v!=k)dfs2(e[i].v,e[i].v,x);
}
void build(int k,int l,int r)
{
t[k].l=l;t[k].r=r;
if(l!=r)
{
int mid=(l+r)>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
}
}
void change(int k,int x,int y)
{
int left=t[k].l,right=t[k].r;
if(left==right){t[k].mx=y;t[k].sum=y;}
else
{
int mid=(left+right)>>;
if(x<=mid)change(k<<,x,y);
else change(k<<|,x,y);
t[k].sum=t[k<<].sum+t[k<<|].sum;
t[k].mx=max(t[k<<].mx,t[k<<|].mx);
}
}
int ask_mx(int k,int l,int r)
{
int left=t[k].l,right=t[k].r;
if(l<=left&&right<=r)return t[k].mx;
else
{
int mid=(left+right)>>,maxs=-inf;
if(l<=mid)maxs=ask_mx(k<<,l,r);
if(r>mid)maxs=max(maxs,ask_mx(k<<|,l,r));
return maxs;
}
}
int ask_sum(int k,int l,int r)
{
int left=t[k].l,right=t[k].r;
if(l<=left&&right<=r)return t[k].sum;
else
{
int mid=(left+right)>>,sums=;
if(l<=mid)sums=ask_sum(k<<,l,r);
if(r>mid)sums+=ask_sum(k<<|,l,r);
return sums;
}
}
int solve_mx(int x,int y)
{
int maxs=-inf;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]])swap(x,y);
maxs=max(maxs,ask_mx(,pos[top[x]],pos[x]));
x=f[top[x]];
}
if(pos[x]>pos[y])swap(x,y);
maxs=max(maxs,ask_mx(,pos[x],pos[y]));
return maxs;
}
int solve_sum(int x,int y)
{
int sums=;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]])swap(x,y);
sums+=ask_sum(,pos[top[x]],pos[x]);
x=f[top[x]];
}
if(pos[x]>pos[y])swap(x,y);
sums+=ask_sum(,pos[x],pos[y]);
return sums;
}
int main()
{
n=read();
for(int i=;i<n;i++)
{
int u=read(),v=read();
insert(u,v);
insert(v,u);
}
for(int i=;i<=n;i++)a[i]=read();
dfs1(,-);
dfs2(,,-);
build(,,n);
for(int i=;i<=n;i++)change(,pos[i],a[i]);
int Q=read();char ch[];
for(int i=;i<=Q;i++)
{
scanf("%s",ch);
int u=read(),v=read();
if(ch[]=='H')change(,pos[u],v);//QAQ 调用线段树必须用新编号,下面用旧编号是因为子程序中用了新编号T_T
if(ch[]=='M')printf("%d\n",solve_mx(u,v));
if(ch[]=='S')printf("%d\n",solve_sum(u,v));
}
return ;
}
【BZOJ】1036 [ZJOI2008]树的统计Count的更多相关文章
- BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)
BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 14354 Solved: 5802 [Subm ...
- bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 10677 Solved: 4313[Submit ...
- Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 11102 Solved: 4490[Submit ...
- 数据结构(LCT动态树):BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12266 Solved: 4945[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )
树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...
- bzoj 1036: [ZJOI2008]树的统计Count 树链剖分+线段树
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 16294 Solved: 6645[Submit ...
- bzoj 1036: [ZJOI2008]树的统计Count (树链剖分+线段树 点权)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 21194 Solved: 8589[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14982 Solved: 6081[Submit ...
随机推荐
- vim 简单用法
vim 是一个纯文本编辑器 模式化的编辑器 1:编辑模式2:输入模式3:末行模式 : 具有命令的接口,在末行模式中可以直接的通过命令修改vim编辑器打开的文本文件 模式转换 1:编辑模式—>输入 ...
- Halcon 学习笔记3 仿射变换
像素的减少 开运算(较少) 腐蚀(去除更多) 对灰度图像的开运算或腐蚀 相当于将灰度图像变暗 像素增加 闭运算(较少) 膨胀(较多) 对灰度图像的闭运算或膨胀 相当于将灰度图像变亮 仿射变换 另外一种 ...
- 51nod 1624 取余最短路(set)
题意: 佳佳有一个n*m的带权矩阵,她想从(1,1)出发走到(n,m)且只能往右往下移动,她能得到的娱乐值为所经过的位置的权的总和. 有一天,她被下了恶毒的诅咒,这个诅咒的作用是将她的娱乐值变为对p取 ...
- openstack的网络配置
首先在浏览器输入咱们的控制节点的ip地址登陆horizon,也就是dashboard控制页面 输入好用户名与密码,这时输入的用户名与密码会与我们的老大哥keystone进行认证.确认你输入的这个用户有 ...
- 【基础】一个简单的MVC实例及故障排除
Controller: public ActionResult Index() { string setting = "ApplicationServices"; var conn ...
- Hbase(二)hbase建表
一.建表高级属性 下面几个 shell 命令在 hbase 操作中可以起到很到的作用,且主要体现在建表的过程中,看 下面几个 create 属性 1.bloomfilter 布隆过滤器 默认是 NON ...
- 【CF601C】Kleofáš and the n-thlon
Portal -->CF601C Description 大概是说\(m\)个人参加\(n\)场比赛,每场一人有一个排名,每场没有两个人排名相同,一个人最后的得分是\(n\)场比赛的排名相加,现 ...
- Java之面向对象编程20170619
/*************************************************************************************************** ...
- PID控制算法的C语言实现六 抗积分饱和的PID控制算法C语言实现
所谓的积分饱和现象是指如果系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而加大,从而导致执行机构达到极限位置,若控制器输出U(k)继续增大,执行器开度不可能再增大,此时计算机输出控制 ...
- mysql group_concat方法用法
目前有三张表: 课程表: course,里面有student_id 学生表: student,里面有 name 字段 中间表(课程和学生一对多): course_student, 里面有 co ...