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

  1. 【洛谷P4719】动态dp 动态dp模板

    题目大意:给你一颗$n$个点的树,点有点权,有$m$次操作,每次操作给定$x$,$y$,表示修改点$x$的权值为$y$. 你需要在每次操作之后求出这棵树的最大权独立集的权值大小. 数据范围:$n,m≤ ...

  2. 【洛谷4719】 动态dp(树链剖分,dp,矩阵乘法)

    前言 其实我只是为了过掉模板而写的ddp,实际应用被吊着锤 Solution 并不想写详细的过程 一句话过程:将子树中轻儿子的贡献挂到这个点上面来 详细版:(引用yyb) 总结一下的话,大致的过程是这 ...

  3. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  4. 洛谷P4719 【模板】"动态 DP"&动态树分治

    [模板]"动态 DP"&动态树分治 第一道动态\(DP\)的题,只会用树剖来做,全局平衡二叉树什么的就以后再学吧 所谓动态\(DP\),就是在原本的\(DP\)求解的问题上 ...

  5. 洛谷P4719 【模板】动态dp(ddp LCT)

    题意 题目链接 Sol 动态dp板子题.有些细节还没搞懂,待我研究明白后再补题解... #include<bits/stdc++.h> #define LL long long using ...

  6. 洛谷 P4719 【模板】动态dp【动态dp】

    是动态dp的板子 大致思想就是用g[u]来表示不包含重链转移的dp值,然后用线段树维护重链,这样线段树的根就相当于这条重链的top的真实dp值 每次修改的时候,修改x点会影响到x到根的真实dp值,但是 ...

  7. 洛谷P4719 动态dp

    动态DP其实挺简单一个东西. 把DP值的定义改成去掉重儿子之后的DP值. 重链上的答案就用线段树/lct维护,维护子段/矩阵都可以.其实本质上差不多... 修改的时候在log个线段树上修改.轻儿子所在 ...

  8. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  9. 洛谷P3928 Sequence2(dp,线段树)

    题目链接: 洛谷 题目大意在描述底下有.此处不赘述. 明显是个类似于LIS的dp. 令 $dp[i][j]$ 表示: $j=1$ 时表示已经处理了 $i$ 个数,上一个选的数来自序列 $A[0]$ 的 ...

  10. 洛谷P2224 [HNOI2001] 产品加工 [DP补完计划,背包]

    题目传送门 产品加工 题目描述 某加工厂有A.B两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成.由于受到机器性能和产品特性的限制,不同的机器加工同一产品所需的时间会不同,若同时 ...

随机推荐

  1. Eclipse_配置_00_资源帖

    1.Eclipse常用设置 2.eclipse设置和优化 3.Eclipse在工作中的一些常用设置及快捷键整理 4.Eclipse常用插件下载地址

  2. 小程序js页面设置上导航颜色

    //导航条颜色更改 wx.setNavigationBarColor({ frontColor: '#ffffff', // 必写项 backgroundColor: '#008de6', // 必写 ...

  3. poj 2719 Faulty Odometer

    Description You are given a car odometer which displays the miles traveled as an integer. The odomet ...

  4. js实现股票实时刷新数据

    近来学习炒股,免不了上班时间看盘,总不能光明正大的用电脑看行情,一直盯着手机影响也不好,容易引起“关注”. 所以就想自己做一个网页来达到看盘的目的,一个只显示几个关键数字的网页肯定不会引起怀疑.有想法 ...

  5. bzoj 3796 Mushroom追妹纸 —— 后缀数组

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3796 先把三个串拼在一起,KMP 求 s1 , s2 中每个位置和 s3 的匹配情况: 注意 ...

  6. 百度地图API的第一次接触

    因为项目的需求,第一次接触了百度API. 第一步:引用百度地图API的脚本 如果在局域网环境中,要把地图文件和js文件都要下载下来 <script type="text/javascr ...

  7. resiprocate使用入门:内网搭建基于repro的sipproxy测试环境

    测试环境 sipproxy:repro + centos 客户端:windows电脑客户端使用X-Lite,手机andriod客户端使用linphone repro配置和启动 log的配置 如果使用默 ...

  8. fabnacii数列

    Fibonacci数 时间限制:3000 ms | 内存限制:65535 KB 难度:1 描述 无穷数列1,1,2,3,5,8,13,21,34,55...称为Fibonacci数列,它可以递归地定义 ...

  9. Windows平台Python编程必会模块之pywin32

    在Windows平台上,从原来使用C/C++编写原生EXE程序,到使用Python编写一些常用脚本程序,成熟的模块的使用使得编程效率大大提高了. 不过,python模块虽多,也不可能满足开发者的所有需 ...

  10. Collection与Map总结

    顺序表和链表统称为线性表:顺序表一般表现为数组,如:ArrayList的实现;链表有单链表.双链表.循环链表的区分,如:LinkedArrayList由双链表+哈希表实现