【算法】树链剖分+线段树

【题解】模板题,见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的更多相关文章

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

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

  2. BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14302  Solved: 5779[Submit ...

  3. BZOJ 1036: [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 14354  Solved: 5802 [Subm ...

  4. bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 10677  Solved: 4313[Submit ...

  5. Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 11102  Solved: 4490[Submit ...

  6. 数据结构(LCT动态树):BZOJ 1036: [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 12266  Solved: 4945[Submit ...

  7. BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )

    树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...

  8. bzoj 1036: [ZJOI2008]树的统计Count 树链剖分+线段树

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 16294  Solved: 6645[Submit ...

  9. bzoj 1036: [ZJOI2008]树的统计Count (树链剖分+线段树 点权)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 21194  Solved: 8589[Submit ...

  10. BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14982  Solved: 6081[Submit ...

随机推荐

  1. Rsyslog-legacy(旧版本语法)配置说明及举例

    1. RULES-书写规则 格式:日志设备(类型).日志级别             日志处理方式 (1)日志类型分类 auth pam产生的日志 authpriv ssh,ftp等登录信息的验证信息 ...

  2. 《DWZ笔记一》<select>动态联动菜单

    联动菜单,即组合框Combo box,在DWZ文档中对组合框combox的是这样描述的: 在传统的select 用class 定义:class=”combox”, html 扩展:保留原有属性name ...

  3. [mysqld_safe]centos7 mysql 安装与配置

    查资料发现是CentOS 7 版本将MySQL数据库软件从默认的程序列表中移除,用mariadb代替了. 有两种解决办法: 安装mariadb [root@a ~]#  yum install mar ...

  4. 软工网络15团队作业4——Alpha阶段敏捷冲刺之Scrum 冲刺博客(Day1)

    概述 Scrum 冲刺博客对整个冲刺阶段起到领航作用,应该主要包含三个部分的内容: ① 各个成员在 Alpha 阶段认领的任务 ② 明日各个成员的任务安排 ③ 整个项目预期的任务量(使用整数表示,与项 ...

  5. 分享:50行代码监听watch小程序的globalData

    监听方法: // 在任何组件.页面,例如页面 const app = getApp( ); Page({ onLoad: function( ) { app.watch$('role', ( val, ...

  6. IIS部署时未能加载程序集"System.Web.Http.WebHost"解决方法

    问题如下 服务器没有安装MVC,下载以下dll覆盖到bin目录下,即可免安装运行程序. 下载地址:https://pan.baidu.com/s/1mhCo5mS

  7. adb命令模拟按键事件KeyCode

    例子: //这条命令相当于按了设备的Backkey键 adb shell input keyevent 4 //可以解锁屏幕 adb shell input keyevent  82 //在屏幕上做划 ...

  8. Vue.js checkbox 练习

    <div id="app"> <input type=" />足球 <input type=" />篮球 <input ...

  9. C#使用 SharpSSH

    准备试一把监控Linux机器 . 附件如下 :http://files.cnblogs.com/files/lclblog/Tamir.SharpSsh.zip

  10. C++解析(25):关于动态内存分配、虚函数和继承中强制类型转换的疑问

    0.目录 1.动态内存分配 1.1 new和malloc的区别 1.2 delete和free的区别 2.虚函数 2.1 构造函数与析构函数是否可以成为虚函数? 2.2 构造函数与析构函数是否可以发生 ...