bzoj 4034: [HAOI2015]T2
4034: [HAOI2015]T2
Description
有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个
Input
第一行包含两个整数 N, M 。表示点数和操作数。
接下来一行 N 个整数,表示树中节点的初始权值。
Output
对于每个询问操作,输出该询问的答案。答案之间用换行隔开。
Sample Input
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3
Sample Output
9
13
HINT
对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不
Source
题解:
树链剖分模板题。
刚学树剖,贴个模板吧。。
#include<stdio.h>
#include<iostream>
using namespace std;
const int N=30005;
#define p1 (p<<1)
#define p2 (p<<1|1)
char c[5];
int Q,n,i,x,y,k,id[N],fa[N],top[N],dep[N],s[N],t[N<<2],T[N<<2];
int tot,head[N],to[N<<1],Next[N<<1];
inline void read(int &v){
char ch,fu=0;
for(ch='*'; (ch<'0'||ch>'9')&&ch!='-'; ch=getchar());
if(ch=='-') fu=1, ch=getchar();
for(v=0; ch>='0'&&ch<='9'; ch=getchar()) v=v*10+ch-'0';
if(fu) v=-v;
}
void add(int x,int y)
{
to[tot]=y;
Next[tot]=head[x];
head[x]=tot++;
}
inline void dfs(int x,int pre)
{
s[x]=1;
for(int i=head[x];i!=-1;i=Next[i])
if(to[i]!=pre)
{
dep[to[i]]=dep[x]+1;
fa[to[i]]=x;
dfs(to[i],x);
s[x]+=s[to[i]];
}
}
inline void Dfs(int x,int v)
{
id[x]=++k;
top[x]=v;
int son=0,i;
for(i=head[x];i!=-1;i=Next[i])
if(dep[to[i]]>dep[x]&&s[to[i]]>s[son]) son=to[i];
if(!son) return;
Dfs(son,v);
for(i=head[x];i!=-1;i=Next[i])
if(dep[to[i]]>dep[x]&&to[i]!=son) Dfs(to[i],to[i]);
}
void update(int l,int r,int x,int y,int p)
{
if(l==r)
{
t[p]=T[p]=y;
return;
}
int mid=(l+r)>>1;
if(x<=mid) update(l,mid,x,y,p1);else update(mid+1,r,x,y,p2);
t[p]=max(t[p1],t[p2]);
T[p]=T[p1]+T[p2];
}
int Max(int l,int r,int x,int y,int p)
{
if(x<=l&&r<=y) return t[p];
int mid=(l+r)>>1,ans=-1e9;
if(x<=mid) ans=Max(l,mid,x,y,p1);
if(y>mid) ans=max(ans,Max(mid+1,r,x,y,p2));
return ans;
}
int Sum(int l,int r,int x,int y,int p)
{
if(x<=l&&r<=y) return T[p];
int mid=(l+r)>>1,ans=0;
if(x<=mid) ans=Sum(l,mid,x,y,p1);
if(y>mid) ans+=Sum(mid+1,r,x,y,p2);
return ans;
}
int solvemax(int x,int y)
{
int ans=-1e9;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans=max(ans,Max(1,n,id[top[x]],id[x],1));
x=fa[top[x]];
}
if(id[x]>id[y]) swap(x,y);
ans=max(ans,Max(1,n,id[x],id[y],1));
return ans;
}
int solvesum(int x,int y)
{
int ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=Sum(1,n,id[top[x]],id[x],1);
x=fa[top[x]];
}
if(id[x]>id[y]) swap(x,y);
ans+=Sum(1,n,id[x],id[y],1);
return ans;
}
int main()
{
read(n);
for(i=1;i<=n;i++) head[i]=-1;
for(i=1;i<=n<<2;i++) t[i]=-1e9;
for(i=1;i<n;i++)
{
read(x),read(y);
add(x,y);
add(y,x);
}
dfs(1,0);
Dfs(1,1);
for(i=1;i<=n;i++)
{
read(x);
update(1,n,id[i],x,1);
}
read(Q);
while(Q--)
{
scanf("%s",c);read(x),read(y);
if(c[1]=='M') printf("%d\n",solvemax(x,y));else
if(c[1]=='S') printf("%d\n",solvesum(x,y));else
update(1,n,id[x],y,1);
}
return 0;
}
bzoj 4034: [HAOI2015]T2的更多相关文章
- bzoj 4034 [HAOI2015] T2(树链剖分,线段树)
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1536 Solved: 508[Submit][Status] ...
- Bzoj 4034: [HAOI2015]T2 树链剖分,子树问题,dfs序
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1841 Solved: 598[Submit][Status] ...
- BZOJ 4034: [HAOI2015]T2( 树链剖分 )
树链剖分...子树的树链剖分序必定是一段区间 , 先记录一下就好了 ------------------------------------------------------------------ ...
- 数据结构(树链剖分):BZOJ 4034: [HAOI2015]T2
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...
- BZOJ 4034 [HAOI2015]T2(树链剖分)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4034 [题目大意] 有一棵点数为 N 的树,以点 1 为根,且树点有边权. 有 M 个 ...
- BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )
BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...
- bzoj 4034: [HAOI2015]树上操作 树链剖分+线段树
4034: [HAOI2015]树上操作 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 4352 Solved: 1387[Submit][Stat ...
- bzoj 4034: [HAOI2015]树上操作 (树剖+线段树 子树操作)
4034: [HAOI2015]树上操作 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 6779 Solved: 2275[Submit][Stat ...
- [BZOJ]4034: [HAOI2015]树上操作
[HAOI2015]树上操作 传送门 题目大意:三个操作 1:a,b,c b节点权值+c 2:a,b,c 以b为根的子树节点权值全部+c 3:a,b 查询b到根路径的权值和. 题解:树链剖分 操作1 ...
随机推荐
- 阿里iconfont引入方法
原文:iconfont的引入方法 第一步:使用font-face声明字体@font-face {font-family: 'iconfont';src: url('iconfont.eot'); ...
- NYOJ 1063 生活的烦恼 (二叉树)
题目链接 描述 生活的暑假刚集训开始,他要决心学好字典树,二叉树,线段树和各种树,但生活在OJ上刷题的时候就遇到了一个特别烦恼的问题.那当然就是他最喜欢的二二叉树咯!题目是这样的:给你一颗非空的二叉树 ...
- 天梯赛 L2-005 集合相似度 (set容器)
给定两个整数集合,它们的相似度定义为:Nc/Nt*100%.其中Nc是两个集合都有的不相等整数的个数,Nt是两个集合一共有的不相等整数的个数.你的任务就是计算任意一对给定集合的相似度. 输入格式: 输 ...
- Hbuilder连接第3方模拟器(夜神)
http://www.bcty365.com/content-146-5148-1.html
- 仿阿里云后台管理界面模板html源码——后台
链接:http://pan.baidu.com/s/1nuH2SPj 密码:ar8o
- 绿色的银行类cms管理系统模板——后台
链接:http://pan.baidu.com/s/1pK7Vu9X 密码:4cc5
- utsrelease.h 包含svn信息
utsrelease.h是一个自动生成的文件,没有办法修改,但这个数据是根据Makefile和.config的内容进行生成的,通过修改这两个文件的内容,可以改变!/usr/src/linux/Make ...
- Guava cache功能简介(转)
原文链接:http://ifeve.com/google-guava-cachesexplained/ 范例 LoadingCache<Key, Graph> graphs = Cache ...
- aws rds
1.还原快照,注意设置安全组的问题:不然会导致还原后连接不上:
- python基础(8)--迭代器、生成器、装饰器
1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优 ...