传送门

Solution

  • \(f_{i,0}\) 表示以i节点为根的子树内,不选i号节点的最大独立集
  • \(f_{i,1}\)表示以i节点为根的子树内,选i号节点的最大独立集
  • \(g_{i,0}\) 表示以i节点为根的子树内,不选i号节点,不算它的重节点子树的最大独立集
  • \(g_{i,1}\) 表示以i节点为根的子树内,选i号节点,不算它的重节点子树的最大独立集

把矩阵乘法的加法改成max,乘法改成加法,仍然符合结合律。

先进行树链剖分,对于同一条链上的点,我们的更新可以写成如下的矩阵乘法:

\[\ \ \ \ \ \ \ \ \ \left[ \begin{matrix} g_{i,0} & g_{i,0} \\ g_{i,1} & 0 \end{matrix} \right] \left[ \begin{matrix} f_{i-1,0}\\ f_{i-1,1} \end{matrix} \right] = \left[ \begin{matrix} f_{i,0}\\ f_{i,1} \end{matrix} \right]
\]

矩阵的右下角是0,但是显然并不影响正确性

用线段树维护区间乘积,每次修改在当前节点到根的路径上进行。

  1. 先单点修改当前点的g值
  2. 用区间乘法算出top节点的f值
  3. 更新top节点的父亲节点的g值
  4. 重复以上操作,直至到根节点
#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
#define MN 100005
int n,m,v[MN];
struct edge{int to,nex;}e[MN<<1];
int hr[MN],en;
inline void ins(int f,int t)
{
e[++en]=(edge){t,hr[f]};hr[f]=en;
e[++en]=(edge){f,hr[t]};hr[t]=en;
}
int mx[MN],siz[MN],top[MN],fa[MN];
void dfs1(int x,int f)
{
siz[x]=1;fa[x]=f;register int i;
for(i=hr[x];i;i=e[i].nex)if(f^e[i].to)
{
dfs1(e[i].to,x);siz[x]+=siz[e[i].to];
if(siz[e[i].to]>siz[mx[x]]) mx[x]=e[i].to;
}
}
void dfs2(int x,int f,int tp)
{
top[x]=tp;if(mx[x]) dfs2(mx[x],x,tp);
register int i;
for(i=hr[x];i;i=e[i].nex)if((e[i].to^f)&&(e[i].to^mx[x])) dfs2(e[i].to,x,e[i].to);
}
struct matrix
{
ll a[2][2];
matrix(){memset(a,0,sizeof a);}
matrix operator * (const matrix &b) const
{
register matrix c;register int i,j,k;
for(i=0;i<2;++i)for(j=0;j<2;j++)for(k=0;k<2;++k)
c.a[i][j]=max(c.a[i][j],b.a[i][k]+a[k][j]);
return c;
}
}t[MN<<2],Ans;
ll g[MN][2],f[MN][2];
int pos[MN],id[MN],dind,st[MN];
void init(int x,int F)
{
register int i;g[x][1]=(ll)v[x];
for(i=hr[x];i;i=e[i].nex)
if((e[i].to^F)&&(e[i].to^mx[x]))
{
init(e[i].to,x);
g[x][0]+=max(f[e[i].to][0],f[e[i].to][1]);
g[x][1]+=f[e[i].to][0];
}
f[x][0]=g[x][0];f[x][1]=g[x][1];
if(mx[x])
{
init(mx[x],x);
f[x][0]+=max(f[mx[x]][0],f[mx[x]][1]);
f[x][1]+=f[mx[x]][0];
}
pos[x]=++dind;id[dind]=x;
if(st[top[x]]==0) st[top[x]]=dind;
}
#define mid (l+r>>1)
void build(int k,int l,int r)
{
if(l==r)
{
t[k].a[0][0]=t[k].a[0][1]=g[id[l]][0];
t[k].a[1][0]=g[id[l]][1];t[k].a[1][1]=0ll;
return;
}
build(k<<1,l,mid);build(k<<1|1,mid+1,r);
t[k]=t[k<<1]*t[k<<1|1];
}
void Modify(int k,int l,int r,int x)
{
if(l==r)
{
t[k].a[0][0]=t[k].a[0][1]=g[id[l]][0];
t[k].a[1][0]=g[id[l]][1];t[k].a[1][1]=0ll;
return;
}
if(x<=mid) Modify(k<<1,l,mid,x);
else Modify(k<<1|1,mid+1,r,x);
t[k]=t[k<<1]*t[k<<1|1];
}
matrix query(int k,int l,int r,int a,int b)
{
if(l==a&&r==b) return t[k];
if(b<=mid) return query(k<<1,l,mid,a,b);
if(a>mid) return query(k<<1|1,mid+1,r,a,b);
return query(k<<1,l,mid,a,mid)*query(k<<1|1,mid+1,r,mid+1,b);
}
ll Que()
{
Ans=query(1,1,n,st[1],pos[1]);
return max(Ans.a[0][0],Ans.a[1][0]);
}
inline void change(int x,ll add)
{
g[x][1]+=add;
while(x!=0){
Modify(1,1,n,pos[x]);
matrix tmp=query(1,1,n,st[top[x]],pos[top[x]]);
ll f0=tmp.a[0][0],f1=tmp.a[1][0];
if(top[x]!=1){
g[fa[top[x]]][1]+=f0-f[top[x]][0];
g[fa[top[x]]][0]+=max(f1,f0)-max(f[top[x]][0],f[top[x]][1]);
}
f[top[x]][0]=f0;f[top[x]][1]=f1;
x=fa[top[x]];
}
}
int main()
{
n=read(),m=read();
register int i,j;
for(i=1;i<=n;i++) v[i]=read();
for(i=1;i<n;i++) ins(read(),read());
dfs1(1,0);dfs2(1,0,1);init(1,0);build(1,1,n);
while(m--)
{
i=read();j=read();
change(i,j-v[i]);v[i]=j;
printf("%lld\n",Que());
}
return 0;
}

Blog来自PaperCloud,未经允许,请勿转载,TKS!

[luogu 4719][模板]动态dp的更多相关文章

  1. [模板] 动态dp

    用途 对于某些树形dp(目前只会树上最大权独立集或者类似的),动态地修改点权,并询问修改后的dp值 做法(树剖版) 以最大权独立集为例 设$f[x][0/1]$表示x选不选,这棵子树的最大权独立集大小 ...

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

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

  3. Luogu P4643 【模板】动态dp

    题目链接 Luogu P4643 题解 猫锟在WC2018讲的黑科技--动态DP,就是一个画风正常的DP问题再加上一个动态修改操作,就像这道题一样.(这道题也是PPT中的例题) 动态DP的一个套路是把 ...

  4. 洛谷4719 【模板】动态dp

    题目:https://www.luogu.org/problemnew/show/P4719 关于动态DP似乎有猫锟的WC2018论文,但找不见:还是算了. http://immortalco.blo ...

  5. 洛谷4719 【模板】动态dp 学习笔记(ddp 动态dp)

    qwq大概是混乱的一个题. 首先,还是从一个比较基础的想法开始想起. 如果每次暴力修改的话,那么每次就可以暴力树形dp 令\(dp[x][0/1]\)表示\(x\)的子树中,是否选择\(x\)这个点的 ...

  6. LG4719 【模板】动态dp 及 LG4751 动态dp【加强版】

    题意 题目描述 给定一棵\(n\)个点的树,点带点权. 有\(m\)次操作,每次操作给定\(x,y\),表示修改点\(x\)的权值为\(y\). 你需要在每次操作之后求出这棵树的最大权独立集的权值大小 ...

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

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

  8. 【模板】动态 DP

    luogu传送门. 最近学了一下动态dp,感觉没有想象的难. 动态DP simple的DP是这样的: 给棵树,每个点给个权值,求一下最大权独立集. 动态DP是这样的: 给棵树,每个点给个权值还到处改, ...

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

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

随机推荐

  1. C# vb .net实现高斯模糊

    在.net中,如何简单快捷地实现Photoshop滤镜组中的高斯模糊效果呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第 ...

  2. 查看font字体文件

    url: http://bluejamesbond.github.io/CharacterMap/ 打开网址后,如下图操作

  3. 不能在本机启动SQL Server服务错误代码126(要在协议里面禁用所有别的VIA,是怎么回事?)

    在启动数据库sql服务的时候提示[Windows 不能在 本地计算机 启动 SQL Server . 有关更多信息,查阅系统事件日志.如果这是非 Microsoft 服务,请与服务厂商联系,并参考特定 ...

  4. sql server 获取某一字段分组数据的前十条记录

    1.sql 语法 select m, n from ( select row_number () over (partition by m order by n desc) rn,--以m分组,分组内 ...

  5. Java编程规范(命名规则)

    1.目的 编程规范是对编程的一种约定,主要作用是增强代码的可读性和可维护性,便于代码重用. 2.命名规则 首先要求程序中的各个要素都遵守命名规则,然后在编码中严格按照编码格式编写代码.命名规则包括以下 ...

  6. SQL+C#:一次多语言混合编程的经验总结

    1.用JAVA做,采取轮询策略: 2.用sql语言+C#混合编程,采取触发策略

  7. wireshark语法小结

    https://blog.csdn.net/cumirror/article/details/7054496 过滤重传包 https://blog.csdn.net/Joseph_ChiRunning ...

  8. JQuery EasyUI treegrid展开与折叠,以及数据加载两次的问题

    问题:做项目的时候遇到代码生成的页面,只默认展开了一级节点,每次操作之后刷新还要手动一级一级展开,太麻烦了 官方API:http://www.jeasyui.net/plugins/186.html ...

  9. [ike][ipsec] child sa rekey机制的细节分析

    子标题:ipsec rekey是否会导致丢包 author: classic_tong 前言 什么叫rekey. rekey是指ipsec的通信两端定期更换加密信道秘钥的机制. 为了安全性考虑,随着秘 ...

  10. Flink原理(二)——资源

    前言 本文主要是想简要说明Flink在集群部署.任务提交.任务运行过程中资源情况,若表述有误欢迎大伙留言分享,非常感谢! 一.集群部署阶段 集群部署这里指的是Flink standalone模式,因为 ...