题目: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的更多相关文章

  1. bzoj 4712 洪水——动态DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4712 因为作为动态DP练习而找到,所以就用动态DP做了,也没管那种二分的方法. 感觉理解似乎 ...

  2. BZOJ 4712 洪水 动态dp(LCT+矩阵乘法)

    把之前写的版本改了一下,这个版本的更好理解一些. 特地在一个链的最底端特判了一下. code: #include <bits/stdc++.h> #define N 200005 #def ...

  3. BZOJ 4712 洪水 (线段树+树剖动态维护DP)

    题目大意:略 题目传送门 数据结构好题,但据说直接上动态DP会容易处理不少,然而蒟蒻不会.一氧化碳大爷说还有一个$log$的做法,然而我只会$log^{2}$的.. 考虑静态时如何处理,设$f[x]$ ...

  4. bzoj 4712: 洪水

    [权限题][https://www.lydsy.com/JudgeOnline/status.php?problem_id=4712&jresult=4] 这道动态\(dp\)终于不是独立集/ ...

  5. 【bzoj4712】洪水 动态dp

    不难发现此题是一道动态$dp$题 考虑此题没有修改怎么做,令$f[i]$表示让以$i$为根的子树被覆盖的最小花费,不难推出$f[i]=min(\sum_{j∈son[i]} f[j],val[i])$ ...

  6. BZOJ4712洪水——动态DP+树链剖分+线段树

    题目描述 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开了创造模式,然后飞到 山顶放了格水.于是小A面前出现了一个瀑布.作为平民的小A只好老实巴交地爬山堵水.那么 ...

  7. BZOJ 4712: 洪水 挖坑待补

    Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) # ...

  8. 4712: 洪水 基于链分治的动态DP

    国际惯例的题面:看起来很神的样子......如果我说这是动态DP的板子题你敢信?基于链分治的动态DP?说人话,就是树链剖分线段树维护DP.既然是DP,那就先得有转移方程.我们令f[i]表示让i子树中的 ...

  9. 【BZOJ4712】洪水(动态dp)

    [BZOJ4712]洪水(动态dp) 题面 BZOJ 然而是权限题QwQ,所以粘过来算了. Description 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开 ...

随机推荐

  1. VS2012+Win7站点公布具体步骤

    VS2012+Win7站点公布详细步骤 本机环境: 本文分三个部分介绍Web项目公布的常规方法,大神级别能够略过,主要是为了方便一些刚開始学习的人. 第一部分:VS2012把项目公布到文件系统. 第二 ...

  2. javascript 高级编程系列 - 基本数据类型

    javascript中的基本数据类型包括: Undefined, Null, Boolean, Number, String 5种数据类型 1. Undefined 类型 (只有一个值 undefin ...

  3. [概率dp] hdu 5378 Leader in Tree Land

    题意: 给你一颗以1位根节点的树.我们定义对于每一个子树,节点权值最大的权值记为这个子树的权值,为你将1~n放到这个树里 满足最大权值仅仅有k个的组合数是多少. 思路: 我们能够知道以每一个节点为子树 ...

  4. python--面向对象—接口

    开放封闭原则依赖导致原则接口隔离原则继承多态抽象类和接口类    编程思想:为子类做规范 归一化设计:几个类都实现了相同的方法 抽象类:最好单继承,且可以简单的实现功能 接口类:可以多继承,且最好不实 ...

  5. caffe搭建--caffe在invidia+cpu 酷睿2Q9300 + ubuntu16.04.2上面的安装和编译过程

    本文原创,转载请注明出处. ------------------------------------------------分割线-------------------------------- 概要 ...

  6. On ROWNUM and Limiting Results

    This issue's Ask Tom column is a little different from the typical column. I receive many questions ...

  7. The type List is not generic(转载)

    错误:The type List is not generic; it cannot be parameterized with arguments <Activity> 代码如下: pu ...

  8. slidemenu

    1. 在github上有一个效果不错的开源库,SlidingMenu 最新的代码下载下来后,会报错: No resource found that matches the given name: at ...

  9. 采用ADM2582E/ADM2587E实现完全半/全双工的RS-485/RS-422接口隔离

    RS-485标准是一种常见的总线架构,其通用性及远距离传输能力使其广泛应用于各种通信接口电路.在多数情况下,由于应用环境的恶劣,需要对RS-485接口采用隔离方案以防止出现接地环路. 对RS-485接 ...

  10. asp.net mvc4 修改密码界面

    1.效果 说明:1.界面不太美观 这里面主要是包括 利用jQuery 插件validate验证form字段,jQuery提交form表单的方式 1.HTML代码 <!DOCTYPE html&g ...