BZOJ4712: 洪水(树链剖分维护Dp)
Description
Input
输入文件第一行包含一个数n,表示树的大小。
Output
对于每次询问操作,输出对应的答案,答案之间用换行隔开。
Sample Input
4 3 2 1
1 2
1 3
4 2
4
Q 1
Q 2
C 4 10
Q 1
Sample Output
1
4
解题思路:
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lll spc<<1
#define rrr spc<<1|1
typedef long long lnt;
const int N=;
struct trnt{
lnt minv;
lnt lzt;
}tr[N<<];
struct pnt{
int hd;
int fa;
int tp;
int dp;
int wgt;
int mxs;
int ind;
lnt val;
lnt f;
lnt sigf;
}p[N];
struct ent{
int twd;
int lst;
}e[N<<];
int cnt;
int n,m;
int dfn;
int plc[N];
char cmd[];
void ade(int f,int t)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
return ;
}
void Basic_dfs(int x,int f)
{
p[x].fa=f;
p[x].dp=p[f].dp+;
p[x].wgt=;
int maxs=-;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==f)
continue;
Basic_dfs(to,x);
p[x].sigf+=p[to].f;
p[x].wgt+=p[to].wgt;
if(maxs<p[to].wgt)
{
maxs=p[to].wgt;
p[x].mxs=to;
}
}
if(!p[x].mxs)
p[x].sigf=0x3f3f3f3f;
p[x].f=std::min(p[x].val,p[x].sigf);
return ;
}
void Build_dfs(int x,int top)
{
if(!x)
return ;
p[x].tp=top;
p[x].ind=++dfn;
plc[dfn]=x;
Build_dfs(p[x].mxs,top);
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].ind)
continue;
Build_dfs(to,to);
}
return ;
}
void pushup(int spc)
{
tr[spc].minv=std::min(tr[lll].minv,tr[rrr].minv);
return ;
}
void add(int spc,lnt v)
{
tr[spc].lzt+=v;
tr[spc].minv-=v;
return ;
}
void pushdown(int spc)
{
if(tr[spc].lzt)
{
add(lll,tr[spc].lzt);
add(rrr,tr[spc].lzt);
tr[spc].lzt=;
}
return ;
}
void build(int l,int r,int spc)
{
if(l==r)
{
tr[spc].minv=p[plc[l]].val-p[plc[l]].sigf;
return ;
}
int mid=(l+r)>>;
build(l,mid,lll);
build(mid+,r,rrr);
pushup(spc);
return ;
}
void update(int l,int r,int pos,int spc,lnt v)
{
if(l==r)
{
add(spc,-v);
return ;
}
int mid=(l+r)>>;
pushdown(spc);
if(pos<=mid)
update(l,mid,pos,lll,v);
else
update(mid+,r,pos,rrr,v);
pushup(spc);
return ;
}
int scupdate(int l,int r,int ll,int rr,int spc,lnt v)
{
if(l>rr||ll>r)
return ;
if(l==r)
{
add(spc,v);
if(tr[spc].minv<=)
return plc[l];
return ;
}
if(ll<=l&&r<=rr&&tr[spc].minv>v)
{
add(spc,v);
return ;
}
int mid=(l+r)>>;
pushdown(spc);
int plcc=scupdate(mid+,r,ll,rr,rrr,v);
if(!plcc)
plcc=scupdate(l,mid,ll,rr,lll,v);
pushup(spc);
return plcc;
}
lnt query(int l,int r,int pos,int spc)
{
if(l==r)
return tr[spc].minv;
int mid=(l+r)>>;
pushdown(spc);
if(pos<=mid)
return query(l,mid,pos,lll);
return query(mid+,r,pos,rrr);
}
void Update(int x,lnt v)
{
if(v<=||!x)
return ;
while(x)
{
int tp=scupdate(,n,p[p[x].tp].ind,p[x].ind,,v);
if(!tp)
x=p[p[x].tp].fa;
else{
Update(p[tp].fa,query(,n,p[tp].ind,)+v);
return ;
}
}
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&p[i].val);
for(int i=;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
ade(a,b);
ade(b,a);
}
Basic_dfs(,);
Build_dfs(,);
build(,n,);
scanf("%d",&m);
while(m--)
{
scanf("%s",cmd+);
if(cmd[]=='Q')
{
int x;
scanf("%d",&x);
printf("%lld\n",std::min(p[x].val,p[x].val-query(,n,p[x].ind,)));
}else{
int x,v;
scanf("%d%d",&x,&v);
if(!v)
continue;
p[x].val+=v;
update(,n,p[x].ind,,v);
lnt tmp=p[x].val-query(,n,p[x].ind,);
p[x].f=std::min(p[x].val,tmp);
Update(p[x].fa,p[x].f+v-p[x].val);
}
}
return ;
}
BZOJ4712: 洪水(树链剖分维护Dp)的更多相关文章
- [bzoj4712] 洪水 [树链剖分+线段树+dp]
题面 传送门 思路 DP方程 首先,这题如果没有修改操作就是sb题,dp方程如下 $dp[u]=max(v[u],max(dp[v]))$,其中$v$是$u$的儿子 我们令$g[u]=max(dp[v ...
- 【BZOJ4712】洪水 树链剖分优化DP+线段树
[BZOJ4712]洪水 Description 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开了创造模式,然后飞到山顶放了格水.于是小A面前出现了一个瀑布.作为 ...
- [BZOJ4712]洪水-[树链剖分+线段树]
Description 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开了创造模式,然后飞到山顶放了格水.于是小A面前出现了一个瀑布.作为平民的小A只好老实巴交地爬 ...
- 【bzoj4712】洪水 树链剖分+线段树维护树形动态dp
题目描述 给出一棵树,点有点权.多次增加某个点的点权,并在某一棵子树中询问:选出若干个节点,使得每个叶子节点到根节点的路径上至少有一个节点被选择,求选出的点的点权和的最小值. 输入 输入文件第一行包含 ...
- Codeforces 856D - Masha and Cactus(树链剖分优化 dp)
题面传送门 题意: 给你一棵 \(n\) 个顶点的树和 \(m\) 条带权值的附加边 你要选择一些附加边加入原树中使其成为一个仙人掌(每个点最多属于 \(1\) 个简单环) 求你选择的附加边权值之和的 ...
- [NOIP2018提高组] 保卫王国 (树链剖分+动态DP)
题面 题目链接-Luogu 题目链接-Loj(要加Freopen) 题解 什么是动态DP? OneInDark:你不需要知道这么多,你只需要知道是利用了广义矩阵乘法就够了! 广义矩乘 广义矩阵乘法,简 ...
- (中等) HDU 5293 Tree chain problem,树链剖分+树形DP。
Problem Description Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There are ...
- [bzoj4712]洪水 线段树+树链剖分维护动态dp+二分
Description 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开了创造模式,然后飞到山顶放了格水.于是小A面前出现了一个瀑布.作为平民的小A只好老实巴交地爬 ...
- bzoj 3672: [Noi2014]购票 树链剖分+维护凸包
3672: [Noi2014]购票 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 480 Solved: 212[Submit][Status][D ...
随机推荐
- 51Nod 1010 只包含因子2 3 5的数(打表+二分)
K的因子中只包含2 3 5.满足条件的前10个数是:2,3,4,5,6,8,9,10,12,15. 所有这样的K组成了一个序列S,现在给出一个数n,求S中 >= 给定数的最小的数. 例如:n = ...
- http://www.open-open.com/lib/tag/ReactiveCocoa
http://www.open-open.com/lib/tag/ReactiveCocoa
- HDU-6109 数据分割 并查集(维护根节点)
题目链接:https://cn.vjudge.net/problem/HDU-6109 题意 给出多组等式不等式 对于每一个式子,首先判断是否不可能 如果不可能,记录本组正确式子的个数,然后进入下一组 ...
- Linux GPT分区表16进制实例分析
Linux GPT分区表16进制实例分析 GPT分区表随着win10的普及,已经在越来越多的新电脑上开始使用了.前段时间的新闻有看到说Intel会在后面的新平台中完全取消CSM支持,这也大概相当于后面 ...
- 介绍静态链接库和动态链接库的差别,及在VC++6.0中的建立和使用
首先介绍一下链接库:链接库分为动态链接库和静态链接库两种 LIB是静态链接库,在程序编译连接的时候是静态链接,其相应的文件格式是.lib. 即当程序採用静态链接库的时候..lib文件里的函数被链接到终 ...
- C#文件拖放至窗口的ListView控件获取文件类型
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- Connect the Campus (Uva 10397 Prim || Kruskal + 并查集)
题意:给出n个点的坐标,要把n个点连通,使得总距离最小,可是有m对点已经连接,输入m,和m组a和b,表示a和b两点已经连接. 思路:两种做法.(1)用prim算法时,输入a,b.令mp[a][b]=0 ...
- [9]EC_屏蔽ecshop云提示no_license
安装完后,打开后台就看到这个,特别烦,想立刻干掉它. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdXB0b255dWFu/font/5a6L5L2T/f ...
- hdoj--3549--Flow Problem(最大流)
Flow Problem Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Tot ...
- Linux常用截图软件
1.Gnome-screenshot 是一款 GNOME 截图工具,顾名思义,它是一款用来对整个屏幕.一个特定的窗口或者用户所定义一些其他区域进行捕获的工具.该工具提供了几个其他的功能,包括对所捕获的 ...