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,又叫管理员)打开 ...
随机推荐
- jQuery中的:input选择器
jQuery中的:input选择器 jQuery中的:input选择器包含input, textarea, select 和 button这些标签. <!DOCTYPE html> < ...
- struts1.3中使用DispatchAction的一个问题
近期做项目发现我们公司的项目是用struts1写的,在多方百度下,总有理解了struts1.3的DispatchAction的使用方法 一:struts.xml文件的配置 <?xml versi ...
- 利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model
利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model 使用场景:网站配置项目,为了便于管理,网站有几个Model类来管理配置文件, 比如ConfigWebsiteMo ...
- iOS 插件制作
概述 我们平时也使用了非常多的xcode插件,尽管官方对于插件制作没有提供不论什么支持,可是载入三方的插件,默认还是被同意的.第三方的插件,须要存放在 ~/Library/Application Su ...
- python--网络编程--socket
网络通信标准---网络协议 互联网协议--osi七层协议 五层协议:应用层:应用层.表示层.会话层 传输层:传输层 网络层:网络层 数据链路层:数据链路层 物理层: ...
- Appium python自动化测试系列之认识Appium(四)
4.1界面认识 在之前安装appium的时候说过我们有两种方法安装,也就有两种结果,一种是有界面的,一种是没有界面的,首先我们先讲一下有界面的,以及界面有哪些东西. 首先看第一幅图,如果你的是win ...
- python中if __name__ == '__main__': 的解析(转载)
当你打开一个.py文件时,经常会在代码的最下面看到if __name__ == '__main__':,现在就来介 绍一下它的作用. 模块是对象,并且所有的模块都有一个内置属性 __name__.一个 ...
- 关于TIME_WAIT状态
前言 为何TCP ”四次分手“ 的过程中会有一个TIME_WAIT状态?这个状态有什么意义呢?这是网络中的一个经典问题,本文将给出精简的回答. 什么是TIME_WAIT状态 这是TCP通信协议中出现的 ...
- 搭建React Native开发环境
搭建React Native开发环境 本文档是Mac下搭建的环境,针对的目标平台不同,以及开发 iOS 和 Android 的不同,环境搭建也有差异. Github地址:https://github. ...
- Spark SQL includes a cost-based optimizer, columnar storage and code generation to make queries fast.
https://spark.apache.org/sql/ Performance & Scalability Spark SQL includes a cost-based optimize ...