洛谷P4719 【模板】动态dp
https://www.luogu.org/problemnew/show/P4719
大概就是一条链一条链的处理(“链”在这里指重链),对于每一条链,对于其上每一个点,先算出它自身和所有轻儿子的贡献,当做这一步中这个点的“权值”,然后就变成序列上dp,直接用线段树维护
线段树版本O(n*log^2)
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
struct E
{
int to,nxt;
}e[];
int f1[],ne;
struct P1
{
ll d[][];//左侧不选/选,右侧不选/选
};
struct P2
{
ll d[];//自身不选/选
};
ll a[];
int sz[],hson[],ff[];
int b[],pl[];
int n,m;
inline ll max1(ll a,ll b)
{
return a>b?a:b;
}
const ll inf1=-0x3f3f3f3f3f3f3f3f;
#define max max1
#define G(x) max1((x),inf1)
inline void merge(P1 &c,const P1 &a,const P1 &b)
{
c.d[][]=G(max(a.d[][]+max(b.d[][],b.d[][]),
a.d[][]+b.d[][]));
c.d[][]=G(max(a.d[][]+max(b.d[][],b.d[][]),
a.d[][]+b.d[][]));
c.d[][]=G(max(a.d[][]+max(b.d[][],b.d[][]),
a.d[][]+b.d[][]));
c.d[][]=G(max(a.d[][]+max(b.d[][],b.d[][]),
a.d[][]+b.d[][]));
}
inline void initnode(P1 &c,const P2 &a)
{
c.d[][]=a.d[];c.d[][]=a.d[];
c.d[][]=c.d[][]=inf1;
}
namespace S
{
#define lc (num<<1)
#define rc (num<<1|1)
P1 d[];
inline void upd(int num){merge(d[num],d[lc],d[rc]);}
P1 x;int L;
void _setx(int l,int r,int num)
{
if(l==r)
{
d[num]=x;
return;
}
int mid=(l+r)>>;
if(L<=mid) _setx(l,mid,lc);
else _setx(mid+,r,rc);
upd(num);
}
P1 getx(int L,int R,int l,int r,int num)
{
if(L<=l&&r<=R) return d[num];
int mid=(l+r)>>;
if(L<=mid&&mid<R)
{
P1 x;
merge(x,getx(L,R,l,mid,lc),getx(L,R,mid+,r,rc));
return x;
}
else if(L<=mid)
return getx(L,R,l,mid,lc);
else if(mid<R)
return getx(L,R,mid+,r,rc);
else
exit(-);
}
}
void dfs1(int u,int fa)
{
sz[u]=;
for(int v,k=f1[u];k;k=e[k].nxt)
if(e[k].to!=fa)
{
v=e[k].to;
ff[v]=u;
dfs1(v,u);
sz[u]+=sz[v];
if(sz[v]>sz[hson[u]]) hson[u]=v;
}
}
P2 d1[];//d1[i]维护i节点及其轻儿子的贡献
P2 d2[];//d2[i]维护i节点(是重链顶)所在重链的dp值
int tp[],dwn[];//链顶,链底
void dfs2(int u,int fa)
{
d1[u].d[]=;d1[u].d[]=a[u];
b[++b[]]=u;pl[u]=b[];
tp[u]=(u==hson[fa])?tp[fa]:u;
if(hson[u]) dfs2(hson[u],u);
dwn[u]=hson[u]?dwn[hson[u]]:u;
int v,k;
for(k=f1[u];k;k=e[k].nxt)
if(e[k].to!=fa&&e[k].to!=hson[u])
{
v=e[k].to;
dfs2(v,u);
d1[u].d[]+=max(d2[v].d[],d2[v].d[]);
d1[u].d[]+=d2[v].d[];
}
initnode(S::x,d1[u]);S::L=pl[u];S::_setx(,n,);
if(u==tp[u])
{
P1 t=S::getx(pl[u],pl[dwn[u]],,n,);
d2[u].d[]=max(t.d[][],t.d[][]);
d2[u].d[]=max(t.d[][],t.d[][]);
}
}
int main()
{
int i,x,y;ll z;P1 t;
scanf("%d%d",&n,&m);
for(i=;i<=n;++i) scanf("%lld",a+i);
for(i=;i<n;++i)
{
scanf("%d%d",&x,&y);
e[++ne].to=y;e[ne].nxt=f1[x];f1[x]=ne;
e[++ne].to=x;e[ne].nxt=f1[y];f1[y]=ne;
}
dfs1(,);
dfs2(,);
while(m--)
{
scanf("%d%lld",&x,&z);
d1[x].d[]-=a[x];a[x]=z;d1[x].d[]+=z;
while(x)
{
initnode(S::x,d1[x]);S::L=pl[x];S::_setx(,n,);
x=tp[x];y=ff[x];
t=S::getx(pl[x],pl[dwn[x]],,n,);
d1[y].d[]-=max(d2[x].d[],d2[x].d[]);
d1[y].d[]-=d2[x].d[];
d2[x].d[]=max(t.d[][],t.d[][]);
d2[x].d[]=max(t.d[][],t.d[][]);
d1[y].d[]+=max(d2[x].d[],d2[x].d[]);
d1[y].d[]+=d2[x].d[];
x=y;
}
//printf("%lld %lld\n",d2[1].d[0],d2[1].d[1]);
printf("%lld\n",max(d2[].d[],d2[].d[]));
}
return ;
}
bst版本O(n*log)
待写
洛谷P4719 【模板】动态dp的更多相关文章
- 【洛谷P4719】动态dp 动态dp模板
题目大意:给你一颗$n$个点的树,点有点权,有$m$次操作,每次操作给定$x$,$y$,表示修改点$x$的权值为$y$. 你需要在每次操作之后求出这棵树的最大权独立集的权值大小. 数据范围:$n,m≤ ...
- 【洛谷4719】 动态dp(树链剖分,dp,矩阵乘法)
前言 其实我只是为了过掉模板而写的ddp,实际应用被吊着锤 Solution 并不想写详细的过程 一句话过程:将子树中轻儿子的贡献挂到这个点上面来 详细版:(引用yyb) 总结一下的话,大致的过程是这 ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- 洛谷P4719 【模板】"动态 DP"&动态树分治
[模板]"动态 DP"&动态树分治 第一道动态\(DP\)的题,只会用树剖来做,全局平衡二叉树什么的就以后再学吧 所谓动态\(DP\),就是在原本的\(DP\)求解的问题上 ...
- 洛谷P4719 【模板】动态dp(ddp LCT)
题意 题目链接 Sol 动态dp板子题.有些细节还没搞懂,待我研究明白后再补题解... #include<bits/stdc++.h> #define LL long long using ...
- 洛谷 P4719 【模板】动态dp【动态dp】
是动态dp的板子 大致思想就是用g[u]来表示不包含重链转移的dp值,然后用线段树维护重链,这样线段树的根就相当于这条重链的top的真实dp值 每次修改的时候,修改x点会影响到x到根的真实dp值,但是 ...
- 洛谷P4719 动态dp
动态DP其实挺简单一个东西. 把DP值的定义改成去掉重儿子之后的DP值. 重链上的答案就用线段树/lct维护,维护子段/矩阵都可以.其实本质上差不多... 修改的时候在log个线段树上修改.轻儿子所在 ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- 洛谷P3928 Sequence2(dp,线段树)
题目链接: 洛谷 题目大意在描述底下有.此处不赘述. 明显是个类似于LIS的dp. 令 $dp[i][j]$ 表示: $j=1$ 时表示已经处理了 $i$ 个数,上一个选的数来自序列 $A[0]$ 的 ...
- 洛谷P2224 [HNOI2001] 产品加工 [DP补完计划,背包]
题目传送门 产品加工 题目描述 某加工厂有A.B两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成.由于受到机器性能和产品特性的限制,不同的机器加工同一产品所需的时间会不同,若同时 ...
随机推荐
- Codeforces 762D Maximum path 动态规划
Codeforces 762D 题目大意: 给定一个\(3*n(n \leq 10^5)\)的矩形,从左上角出发到右下角,规定每个格子只能经过一遍.经过一个格子会获得格子中的权值.每个格子的权值\(a ...
- Redis 客户端安装与远程连接图解
Linux环境:Centos 6.8 Redis服务端版本:3.2.6 Redis客户端下载链接:https://redisdesktop.com/download 省略Linux系统安装Redis教 ...
- 洛谷P1092虫食算——深搜
题目:https://www.luogu.org/problemnew/show/P1092 剪枝1:从右往左.从上往下按字母出现顺序搜索: 剪枝2:同一列前两个数字确定,可直接算出第三个数字并判断: ...
- Html5 canvas 元素
canvas 元素用于在网页上绘制图形. 什么是 Canvas? HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像. 画布是一个矩形区域,您可以控制其每一像素. canv ...
- Python3解leetcode Same Tree
问题描述: Given two binary trees, write a function to check if they are the same or not. Two binary tree ...
- xml约束(转)
在XML技术里,可以编写一个文档来约束一个XML文档的书写规范,这称之为XML约束. 常用的约束技术XML DTD :XML Schema. XML Schema 也是一种用于定义和描述 XML 文档 ...
- c/c++语言实现tesseract ocr引擎编程实例
编译下面的程序操作系统必须在安装了tesseract库和leptonica库才可以 Basic example c++ code: #include <tesseract/baseapi.h&g ...
- 无法加载MainifestResourceTransformer
Cannot load implementation hint 'org.apache.maven.plugins.shade.resource.MainifestResourceTransforme ...
- Netty入门系列(3) --使用Netty进行编解码的操作
前言 何为编解码,通俗的来说,我们需要将一串文本信息从A发送到B并且将这段文本进行加工处理,如:A将信息文本信息编码为2进制信息进行传输.B接受到的消息是一串2进制信息,需要将其解码为文本信息才能正常 ...
- Android权限之三共享UID和签名
http://blog.csdn.net/a345017062/article/details/6236263 共享UID 安装在设备中的每一个Android包文件(.apk)都会被分配到一个属于自己 ...