题解:

注意题目说了每个点的权值只能增加

每个点的dp方程比较简单 min(v[i],sum[i])

那么我们考虑如果v[i]增加那么上面使用sum[i]的会带来影响

暴力的做就是一个个往上查然后修改

比较显然的是这个东西可以二分

我们维护v[i]-sum[i]的值,查到那个不符合的就可以了

这样我们就变成了花log^2n的时间对v[i]>sum[i]的变成v[i]<sum[i]

而每次操作最多增加一个v[i]>sum[i]

所以复杂度是对的

树链剖分维护,复杂度nlog^2n

还是比较考验代码能力的

树剖那里一定要理清楚思路

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rint register ll
#define rll register ll
#define IL inline
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
const ll N=2e5+1e4;
const ll N2=N*;
const ll INF=1e9;
ll n,m,v[N],head[N],id[N],rel[N],yz[N],fa[N],f[N],son[N],g[N],num[N],top[N],l;
ll data[N2],cnt,lazy[N2];
struct re{
ll a,b,c;
}e[N*];
void arr(ll x,ll y)
{
e[++l].a=head[x];
e[l].b=y;
head[x]=l;
}
void dfs(ll x,ll y)
{
f[x]=v[x]; num[x]=; fa[x]=y;
ll sum=;
for (rint u=head[x];u;u=e[u].a)
{
rint v=e[u].b;
if (v!=y)
{
yz[x]=;
dfs(v,x);
sum+=f[v];
num[x]+=num[v];
if (num[v]>num[son[x]]) son[x]=v;
}
}
if (sum) f[x]=min(f[x],sum);
if (sum) g[x]=sum; else g[x]=f[x];
}
void dfs2(ll x,ll y,ll z)
{
id[x]=++cnt; rel[cnt]=x;
top[x]=y;
if (!son[x]) return;
dfs2(son[x],y,x);
for (rint u=head[x];u;u=e[u].a)
{
rint v=e[u].b;
if (v!=z&&v!=son[x]) dfs2(v,v,x);
}
}
#define updata(x) data[x]=min(data[x*2],data[x*2+1])
#define mid ((h+t)/2)
IL void down(ll x)
{
if (!lazy[x]) return;
lazy[x*]+=lazy[x]; lazy[x*+]+=lazy[x];
data[x*]-=lazy[x]; data[x*+]-=lazy[x];
lazy[x]=;
}
void build(ll x,ll h,ll t)
{
if (h==t)
{
data[x]=v[rel[h]]-g[rel[h]];
return;
}
build(x*,h,mid); build(x*+,mid+,t);
updata(x);
}
ll query(ll x,ll h,ll t,ll pos)
{
if (h==t)
{
if (data[x]>) return(v[rel[h]]-data[x]);
else return(v[rel[h]]);
}
down(x);
if (pos<=mid) return(query(x*,h,mid,pos));
else return(query(x*+,mid+,t,pos));
updata(x);
}
void change2(ll x,ll h,ll t,ll h1,ll t1,ll k)
{
if (h1<=h&&t<=t1)
{
lazy[x]+=k; data[x]-=k; return;
}
down(x);
if (h1<=mid) change2(x*,h,mid,h1,t1,k);
if (mid<t1) change2(x*+,mid+,t,h1,t1,k);
updata(x);
}
ll query2(ll x,ll h,ll t,ll h1,ll t1)
{
if (h1<=h&&t<=t1)
{
return(data[x]);
}
down(x);
ll ans=INF;
if (h1<=mid) ans=min(ans,query2(x*,h,mid,h1,t1));
if (mid<t1) ans=min(ans,query2(x*+,mid+,t,h1,t1));
return(ans);
}
vector<re> ve;
void find2(ll x,ll h,ll t,ll h1,ll t1)
{
if (h1<=h&&t<=t1)
{
ve.push_back((re){x,h,t}); return;
}
down(x);
if (h1<=mid) find2(x*,h,mid,h1,t1);
if (mid<t1) find2(x*+,mid+,t,h1,t1);
}
ll find3(ll x,ll h,ll t,ll k)
{
if (h==t) return(h);
down(x);
if (data[x*+]<k) return(find3(x*+,mid+,t,k));
else return(find3(x*,h,mid,k));
}
void change(rll x,rll y)
{
if (!y) return;
rll now=x;
while (top[now])
{
if (query2(,,n,id[top[now]],id[now])>=y)
{
change2(,,n,id[top[now]],id[now],y); //v[x]-g[x] 减小y
} else
{
ve.clear();
find2(,,n,id[top[now]],id[now]);
rll l=int(ve.size())-;
rll k;
dep(i,l,)
if (data[ve[i].a]<y)
{
k=find3(ve[i].a,ve[i].b,ve[i].c,y); // k.a 位置 k.b v[x]-g[x]
break;
}
rll x1=query(,,n,k);
change2(,,n,k,id[now],y);
rll x2=query(,,n,k);
change(fa[rel[k]],x2-x1);
break;
}
now=fa[top[now]];
}
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n;
rep(i,,n) cin>>v[i];
rep(i,,n-)
{
ll x,y; cin>>x>>y;
arr(x,y); arr(y,x);
}
dfs(,);
dfs2(,,);
build(,,n);
cin>>m;
char cc;
rep(i,,m)
{
ll x,y;
cin>>cc;
if (cc=='Q')
{
cin>>x;
cout<<query(,,n,id[x])<<endl;
} else
{
cin>>x>>y;
ll x1=query(,,n,id[x]);
v[x]+=y;
if (yz[x])
{
change2(,,n,id[x],id[x],-y);
ll x3=query(,,n,id[x]);
if (x3>x1) change(fa[x],x3-x1);
}
else change(fa[x],y);
}
}
return ;
}

【BZOJ4712】洪水的更多相关文章

  1. [bzoj4712]洪水_动态dp

    洪水 bzoj-4712 题目大意:给定一棵$n$个节点的有根树.每次询问以一棵节点为根的子树内,选取一些节点使得这个被询问的节点包含的叶子节点都有一个父亲被选中,求最小权值.支持单点修改. 注释:$ ...

  2. BZOJ4712 : 洪水

    首先不难列出DP方程: $dp[x]=\min(w[x],h[x])$ $h[x]=\sum dp[son]$ 当$w[x]$增加时,显然$dp[x]$不会减少,那么我们求出$dp[x]$的增量$de ...

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

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

  4. 2018.10.12 bzoj4712: 洪水(树链剖分)

    传送门 树链剖分好题. 考虑分开维护重儿子和轻儿子的信息. 令f[i]f[i]f[i]表示iii为根子树的最优值,h[i]h[i]h[i]表示iii重儿子的最优值,g[i]g[i]g[i]表示iii所 ...

  5. [bzoj4712]洪水 线段树+树链剖分维护动态dp+二分

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

  6. [BZOJ4712]洪水-[树链剖分+线段树]

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

  7. [bzoj4712] 洪水 [树链剖分+线段树+dp]

    题面 传送门 思路 DP方程 首先,这题如果没有修改操作就是sb题,dp方程如下 $dp[u]=max(v[u],max(dp[v]))$,其中$v$是$u$的儿子 我们令$g[u]=max(dp[v ...

  8. BZOJ4712: 洪水(树链剖分维护Dp)

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

  9. bzoj4712 洪水(动态dp)

    看起来很模板的一个题啊 qwq 但是我还是wei 题目要求的是一个把根节点和所有叶子断开连接的最小花费. 还是想一个比较\(naive\)的做法 我们令\(dp1[i]\)表示,在\(i\)的子树内, ...

  10. 动态 DP 学习笔记

    不得不承认,去年提高组 D2T3 对动态 DP 起到了良好的普及效果. 动态 DP 主要用于解决一类问题.这类问题一般原本都是较为简单的树上 DP 问题,但是被套上了丧心病狂的修改点权的操作.举个例子 ...

随机推荐

  1. ubuntu16.04彻底删除nginx+php

    1.1 删除nginx,–purge包括配置文件 sudo apt-get --purge remove nginx 1.2 自动移除全部不使用的软件包 sudo apt-get autoremove ...

  2. 生产环境elasticsearch5.0报错IllegalArgumentException: number of documents in the index cannot exceed 2147483519的处理

    最近几天的push:user:req数据写不到集群,报错如下: [--13T09::,][DEBUG][o.e.a.b.TransportShardBulkAction] [yunva_etl_es8 ...

  3. Kendo ui 入门知识点

    1. Kendo的继承 varPerson= kendo.Class.extend({...}); var person = new person(); var Parent = kendo.Clas ...

  4. mgo 的 session 与连接池

    简介 mgo是由Golang编写的开源mongodb驱动.由于mongodb官方并没有开发Golang驱动,因此这款驱动被广泛使用.mongodb官网也推荐了这款开源驱动,并且作者在github也表示 ...

  5. Socket实现断线重连

    客户端维护一个线程安全的待发送信息队列   开启死循环   判断Socket = null   调用Socket的sendUrgentData(0xFF)发送1个字节的心跳包   捕捉到连接异常后就关 ...

  6. 技术的热门度曲线:GHC

      全球最大的 IT 咨询公司高德纳(Gartner),有一个"技术热门度曲线"模型(Gartner Hype Cycle). 该模型认为,一门技术的发展要经历五个阶段. (1)启 ...

  7. ORACLE in与exists语句的区别

    select * from A where id in(select id from B) 以上查询使用了in语句,in()只执行一次,它查出B表中的所有id字段并缓存起来.之后,检查A表的id是否与 ...

  8. LeetCode(98): 验证二叉搜索树

    Medium! 题目描述: 给定一个二叉树,判断其是否是一个有效的二叉搜索树. 一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右 ...

  9. MYSQL安装报错 -- 出现Failed to find valid data directory.

    运行环境:windows10数据库版本:mysql.8.0.12安装方式:rpm包直接安装 问题描述:mysql初始化的时候找不到对应的数据库存储目录 报错代码: 2018-10-13T03:29:2 ...

  10. laravel Blade 模板引擎

    与视图文件紧密关联的就是模板代码,我们在视图文件中通过模板代码和 HTML 代码结合实现视图的渲染.和很多其他后端语言不同,PHP 本身就可以当做模板语言来使用,但是这种方式有很多缺点,比如安全上的隐 ...