bzoj 4712 洪水 —— 动态DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4712
设 f[x] = min(∑f[u] , a[x]),ls = ∑f[lson]
矩阵是这样的:
ls, a[x]
0, 0
所以假如后面乘一个
f[u], 0
0, 0
就得到了 f[x];
注意,因为定义结构体时把数组都赋成 inf 了,所以后面要用 0 时必须专门赋值成 0;
查询时不是从重链顶开始的,所以不用 get,直接 query(x,ed[top[x]]);
最后 f[x] 和 a[x] 再取一下 min 即可(相当于乘全是0的矩阵)。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mid ((l+r)>>1)
#define ls (x<<1)
#define rs (x<<1|1)
using namespace std;
typedef long long ll;
int const xn=2e5+;
int n,hd[xn],ct,to[xn<<],nxt[xn<<],fa[xn],dfn[xn],siz[xn],son[xn];
int id[xn],tim,top[xn],ed[xn];
ll a[xn],f[xn],inf=1e10;
ll mnn(ll a,ll b){return a<b?a:b;}
struct N{
ll a[][];
N(){a[][]=a[][]=a[][]=a[][]=inf;}
N operator * (const N &y) const
{
N ret;
for(int i=;i<;i++)
for(int k=;k<;k++)
for(int j=;j<;j++)
ret.a[i][j]=mnn(ret.a[i][j],a[i][k]+y.a[k][j]);
return ret;
}
}t[xn<<],s[xn];
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
void dfs(int x,int ff)
{
fa[x]=ff; siz[x]=;
for(int i=hd[x],u;i;i=nxt[i])
{
if((u=to[i])==ff)continue;
dfs(u,x); siz[x]+=siz[u];
if(siz[u]>siz[son[x]])son[x]=u;
}
}
void dfs2(int x)
{
dfn[x]=++tim; id[tim]=x; f[x]=a[x]; ll tmp=;
s[dfn[x]].a[][]=inf; s[dfn[x]].a[][]=a[x];//
s[dfn[x]].a[][]=s[dfn[x]].a[][]=;//!!!
if(son[x])top[son[x]]=top[x],dfs2(son[x]);
else {ed[top[x]]=dfn[x]; return;}//!son: a[0][0]=inf
for(int i=hd[x],u;i;i=nxt[i])
if((u=to[i])!=fa[x]&&u!=son[x])
{
top[u]=u; dfs2(u);
tmp+=f[u];
}
s[dfn[x]].a[][]=tmp;
f[x]=mnn(a[x],tmp+f[son[x]]);
}
void build(int x,int l,int r)
{
if(l==r){t[x]=s[l]; return;}
build(ls,l,mid); build(rs,mid+,r);
t[x]=t[ls]*t[rs];
}
void upt(int x,int l,int r,int pos)
{
if(l==r){t[x]=s[l]; return;}
if(pos<=mid)upt(ls,l,mid,pos);
else upt(rs,mid+,r,pos);
t[x]=t[ls]*t[rs];
}
N query(int x,int l,int r,int L,int R)
{
if(l>=L&&r<=R)return t[x];
if(mid>=R)return query(ls,l,mid,L,R);
if(mid<L)return query(rs,mid+,r,L,R);
return query(ls,l,mid,L,R)*query(rs,mid+,r,L,R);
}
N get(int x){return query(,,n,dfn[x],ed[x]);}
void chg(int x,int ss)
{
s[dfn[x]].a[][]+=ss;//dfn[x]
N pr,nw;
while(x)
{
pr=get(top[x]); upt(,,n,dfn[x]); nw=get(top[x]);
x=fa[top[x]];
s[dfn[x]].a[][]+=mnn(nw.a[][],nw.a[][])-mnn(pr.a[][],pr.a[][]);//
}
}
char ch[];
int main()
{
n=rd();
for(int i=;i<=n;i++)a[i]=rd();
for(int i=,x,y;i<n;i++)x=rd(),y=rd(),add(x,y),add(y,x);
dfs(,); top[]=; dfs2(); build(,,n);
int m=rd();
for(int i=,x,v;i<=m;i++)
{
scanf("%s",ch); x=rd();
if(ch[]=='C')v=rd(),chg(x,v);
else
{
N tmp=query(,,n,dfn[x],ed[top[x]]);//
printf("%lld\n",mnn(tmp.a[][],tmp.a[][]));
}
}
return ;
}
bzoj 4712 洪水 —— 动态DP的更多相关文章
- bzoj 4712 洪水——动态DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4712 因为作为动态DP练习而找到,所以就用动态DP做了,也没管那种二分的方法. 感觉理解似乎 ...
- BZOJ 4712 洪水 动态dp(LCT+矩阵乘法)
把之前写的版本改了一下,这个版本的更好理解一些. 特地在一个链的最底端特判了一下. code: #include <bits/stdc++.h> #define N 200005 #def ...
- BZOJ 4712 洪水 (线段树+树剖动态维护DP)
题目大意:略 题目传送门 数据结构好题,但据说直接上动态DP会容易处理不少,然而蒟蒻不会.一氧化碳大爷说还有一个$log$的做法,然而我只会$log^{2}$的.. 考虑静态时如何处理,设$f[x]$ ...
- bzoj 4712: 洪水
[权限题][https://www.lydsy.com/JudgeOnline/status.php?problem_id=4712&jresult=4] 这道动态\(dp\)终于不是独立集/ ...
- 【bzoj4712】洪水 动态dp
不难发现此题是一道动态$dp$题 考虑此题没有修改怎么做,令$f[i]$表示让以$i$为根的子树被覆盖的最小花费,不难推出$f[i]=min(\sum_{j∈son[i]} f[j],val[i])$ ...
- BZOJ4712洪水——动态DP+树链剖分+线段树
题目描述 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开了创造模式,然后飞到 山顶放了格水.于是小A面前出现了一个瀑布.作为平民的小A只好老实巴交地爬山堵水.那么 ...
- BZOJ 4712: 洪水 挖坑待补
Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) # ...
- 4712: 洪水 基于链分治的动态DP
国际惯例的题面:看起来很神的样子......如果我说这是动态DP的板子题你敢信?基于链分治的动态DP?说人话,就是树链剖分线段树维护DP.既然是DP,那就先得有转移方程.我们令f[i]表示让i子树中的 ...
- 【BZOJ4712】洪水(动态dp)
[BZOJ4712]洪水(动态dp) 题面 BZOJ 然而是权限题QwQ,所以粘过来算了. Description 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开 ...
随机推荐
- Opencv 最小外接矩形合并拼接
前一篇画出了最小外接矩形,但是有时候画出来的矩形由于中间像素干扰或者是其他原因矩形框并不是真正想要的 如图1是一个信号的雨图,被矩形框分割成了多个小框: 需要合并矩形框达到的效果: 主要思想: 扫描两 ...
- mysql insert into 时报1062错误
插入数据库时报1062错误,并没有错误详解 而网上的原因大多是主键重复,找了半天并没有解决办法 最后发现是表设置了联合唯一 ,插入的数据和之前的一样 >_< 太真实了
- 【网络协议】TCP的流量控制机制
一般来说,我们总是希望传输数据的更快一些,但假设发送方把数据发送的非常快.而接收方来不及接收,这就可能造成数据的丢失.流量控制就是让发送方的发送速率不要太快.让接收方来得及接收. 对于成块数据流,TC ...
- HDFS源代码分析(二)-----元数据备份机制
前言 在Hadoop中,全部的元数据的保存都是在namenode节点之中,每次又一次启动整个集群,Hadoop都须要从这些持久化了的文件里恢复数据到内存中,然后通过镜像和编辑日志文件进行定期的扫描与合 ...
- Ubuntu16.04 下docker部署web项目
概念性的请戳 第一步:更新apt-get update 第二步:安装环境 apt-get install \ apt-transport-https \ ca-certificates \ curl ...
- ZOJ 1516 Uncle Tom's Inherited Land(二分匹配 最大匹配 匈牙利啊)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=516 Your old uncle Tom inherited a p ...
- JavaScript根据Json数据来做的模糊查询功能
类似于百度搜索框的模糊查找功能 需要有有已知数据,实现搜索框输入字符,然后Js进行匹配,然后可以通过鼠标点击显示的内容,把内容显示在搜索框中 当然了,正则只是很简单的字符匹配,不具备多么复杂的判断 & ...
- EasyRTMP视频直播推送H264 sps解析错误导致播放画面拉伸问题解决
EasyRTMP是将H264流以及AAC流以RTMP协议推送到RTMP服务器上进行直播.EasyRTMP推送库中会从H264流中提取中SPS.PPS进行解析,开发的时候遇到过有些SPS解析有误,获取到 ...
- mybatis入门(八)
mybatis入门---更新和删除 <!-- 删除用户 --> <delete id="deleteUser" parameterType="java. ...
- C++ ini解析器
在gitee上找到的一个很好用的ini文件解析器,纯C++代码,移植方便. 项目地址:https://gitee.com/sollyu/IniParser 稍微修改了下,去掉了Windows平台相关定 ...