正题

题目链接:https://www.luogu.org/problemnew/show/P4719\texttt{https://www.luogu.org/problemnew/show/P4719}https://www.luogu.org/problemnew/show/P4719


题目大意

每次修改一个点权,求最大权独立集。


解题思路

首先考虑普通dpdpdp,设fi,0/1f_{i,0/1}fi,0/1​表示iii的子树,是否选择自己这个点的最大权独立集。
然后十分显然fx,0=∑max{fy,0,fy,1}f_{x,0}=\sum max\{f_{y,0},f_{y,1}\}fx,0​=∑max{fy,0​,fy,1​}
fx,1=∑fy,0f_{x,1}=\sum f_{y,0}fx,1​=∑fy,0​

我们考虑将其转换矩阵乘法,首先扩展为Ci,j=max{Ai,k+Bk,j}C_{i,j}=max\{A_{i,k}+B_{k,j}\}Ci,j​=max{Ai,k​+Bk,j​}
然后考虑转换上面的公式。
然后设gi,0/1g_{i,0/1}gi,0/1​表示在iii的子树中,不在iii的重链上的子孙,是否选择自己这个点的最大权独立集
那么有
gi,0=fi,0+max{gi+1,0,gi+1,1}g_{i,0}=f_{i,0}+max\{g_{i+1,0},g_{i+1,1}\}gi,0​=fi,0​+max{gi+1,0​,gi+1,1​}
gi,1=fi,1+gi+1,0g_{i,1}=f_{i,1}+g_{i+1,0}gi,1​=fi,1​+gi+1,0​
然后构造矩阵
[fi,0fi,0fi,10]∗[gi+1,0gi+1,1]=[gi,0gi,1]\begin{bmatrix} f_{i,0} & f_{i,0} \\ f_{i,1} & 0 \end{bmatrix}* \begin{bmatrix} g_{i+1,0}\\ g_{i+1,1} \end{bmatrix}= \begin{bmatrix} g_{i,0}\\ g_{i,1} \end{bmatrix}[fi,0​fi,1​​fi,0​0​]∗[gi+1,0​gi+1,1​​]=[gi,0​gi,1​​]

然后每次修改时我们用矩阵val(i)val(i)val(i)表示iii的单独矩阵,然后我们修改后带回到线段树中,然后重新计算出新的val(i)val(i)val(i)


codecodecode

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll Size=2,N=1e5+100;
ll n,m,tot,cnt,ls[N],fa[N],v[N],f[N][2];
ll seg[N],id[N],top[N],siz[N],son[N],ed[N];
struct matrix{ll a[Size][Size];
}val[N];
matrix operator*(matrix a,matrix b)
{matrix c;memset(c.a,0,sizeof(c.a));for(ll i=0;i<Size;i++)for(ll j=0;j<Size;j++)for(ll k=0;k<Size;k++)c.a[i][j]=max(c.a[i][j],a.a[i][k]+b.a[k][j]);return c;
}
struct Tree_node{ll l,r;matrix g;
};
struct Edge_node{ll to,next;
}a[N<<1];
struct Line_cut_tree{Tree_node t[N<<2];void Build(ll x,ll l,ll r){t[x].l=l;t[x].r=r;if(l==r){ll u=seg[l],g0=0,g1=v[seg[l]];for(ll i=ls[u];i;i=a[i].next){ll y=a[i].to;if(y==fa[u]||y==son[u]) continue;g0+=max(f[y][0],f[y][1]),g1+=f[y][0];}t[x].g.a[0][0]=t[x].g.a[0][1]=g0;t[x].g.a[1][0]=g1;val[l]=t[x].g;return;}ll mid=(l+r)/2;Build(x*2,l,mid);Build(x*2+1,mid+1,r);t[x].g=t[x*2].g*t[x*2+1].g;}matrix Query(ll x,ll l,ll r){if(t[x].l==l&&t[x].r==r)return t[x].g;if(t[x*2].r>=r) return Query(x*2,l,r);if(t[x*2+1].l<=l) return Query(x*2+1,l,r);return Query(x*2,l,t[x*2].r)*Query(x*2+1,t[x*2+1].l,r);}void Change(ll x,ll z){if(t[x].l==t[x].r){t[x].g=val[t[x].l];return;}if(t[x*2].r>=z) Change(x*2,z);else Change(x*2+1,z);t[x].g=t[x*2].g*t[x*2+1].g;}
}Tree;
void addl(ll x,ll y)
{a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;
}
void dfs1(ll x,ll Fa)
{siz[x]++;fa[x]=Fa;f[x][1]=max(v[x],0ll);for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==Fa)continue;dfs1(y,x);f[x][0]+=max(f[y][0],f[y][1]);f[x][1]+=f[y][0];siz[x]+=siz[y];if(siz[y]>siz[son[x]]) son[x]=y;}
}
void dfs2(ll x,ll fa)
{id[x]=++cnt;seg[cnt]=x;if(son[x]){top[son[x]]=top[x];dfs2(son[x],x);}else ed[top[x]]=cnt;for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa||y==son[x]) continue;top[y]=y;dfs2(y,x);}
}
matrix ask(ll x)
{return Tree.Query(1,id[top[x]],ed[top[x]]);}
void path_change(ll x,ll w)
{val[id[x]].a[1][0]+=w-v[x];v[x]=w;matrix old,news;while(x){old=ask(top[x]);Tree.Change(1,id[x]);news=ask(top[x]);x=fa[top[x]];val[id[x]].a[0][0]+=max(news.a[0][0],news.a[1][0])-max(old.a[0][0],old.a[1][0]);val[id[x]].a[0][1]=val[id[x]].a[0][0];val[id[x]].a[1][0]+=news.a[0][0]-old.a[0][0];}
}
int main()
{scanf("%lld%lld",&n,&m);for(ll i=1;i<=n;i++)scanf("%lld",&v[i]);for(ll i=1;i<n;i++){ll x,y;scanf("%lld%lld",&x,&y);addl(x,y);addl(y,x);}top[1]=1;dfs1(1,0);dfs2(1,0);Tree.Build(1,1,n);matrix ans;while(m--){ll x,w;scanf("%lld%lld",&x,&w);path_change(x,w);ans=ask(1);printf("%lld\n",max(ans.a[0][0],ans.a[1][0]));}
}

P4719-[模板]动态DP【矩阵乘法,树链剖分,线段树】相关推荐

  1. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MB Submit: 1153  Solved: 421 [Submit][Sta ...

  2. CodeForces - 609E Minimum spanning tree for each edge(最小生成树+树链剖分+线段树/树上倍增)

    题目链接:点击查看 题目大意:给出一张 n 个点和 m 条边组成的无向图,现在询问包含每一条边的最小生成树 题目分析:考虑求解次小生成树的思路: 求出最小生成树 ans 枚举每一条非树边 ( u , ...

  3. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  4. BZOJ3862Little Devil I——树链剖分+线段树

    题目大意: 给一棵树,每条边可能是黑色或白色(起始都是白色),有三种操作: 1.将u到v路径上所有边颜色翻转(黑->白,白->黑) 2.将只有一个点在u到v路径上的边颜色翻转 3.查询u到 ...

  5. CodeForces - 160D Edges in MST(思维+tarjan/树链剖分+线段树)

    题目链接:点击查看 题目大意:给出一张 n 个点 m 条边组成的带权无向图,现在对于每条边来说,确定一下其分类: 一定是最小生成树上的边 可能是最小生成树上的边 一定不是最小生成树的边 题目分析:两种 ...

  6. P2486 [SDOI2011]染色(树链剖分+线段树)

    题干描述 输入描述 输出格式 对于每个询问操作,输出一行答案. 输入输出样例 输入 #1 复制 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C 2 1 1 Q ...

  7. BZOJ4127Abs——树链剖分+线段树

    题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...

  8. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  9. BZOJ2325[ZJOI2011]道馆之战——树链剖分+线段树

    题目描述 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中 的每一个冰块都只能经过一次.当一个冰地上的所有冰块都被经过之后,到下一个冰地的楼梯才 ...

  10. YbtOJ-染色计划【树链剖分,线段树,tarjan】

    正题 题目大意 给出nnn个点的一棵树,每个点有个颜色aia_iai​,你每次可以选择一个颜色全部变成另一个颜色. 求最少多少次操作可以把一种颜色变成一个完整的连通块. 1≤k≤n≤2×1051\le ...

最新文章

  1. matlab图形绘制经典案例,MATLAB经典教程第四章_图形绘制.ppt
  2. 进程外Session和进程内Session存储
  3. 说说几个 Python 内存分配时的小秘密
  4. KMP算法的Next数组详解(转)
  5. qam已调信号matlab相干解调,16qam调制解调matlab
  6. VS2013正在等待所需操作完成
  7. 块状元素的居中,首先设置宽度,再设 margin: 0 auto
  8. openstack云计算实践-老男孩架构师课程教案笔记分享
  9. android编译make错误——javalib.jar invalid header field”、classes-full-debug.jar 错误 41 ...
  10. JavaWeb宠物管理系统(源码+文档)
  11. PHP代码审计11—逻辑漏洞
  12. oracle导出excel数据变成科学计数法
  13. java 单位圆_巧用蒙特卡洛算法求单位圆面积
  14. nodejs使用emailjs发送邮箱邮件
  15. 2023真无线蓝牙耳机怎么选?值得入手的蓝牙耳机推荐
  16. 猿创征文 |【gin-vue-admin】后端结构设计和基本工作原理
  17. 朋友圈变美靠AI:新型美颜技术实现细粒度颜值提升
  18. ubuntu vim的 保存退出方法
  19. setClickable,setEnabled,setFocusable 的区别
  20. node sass 报错解决方法 Module build failed (from ./node_modules/sass-loader/dist/cjs.js)

热门文章

  1. java实验3_Java 实验3
  2. 一个问题让我直接闭门思过!!!拼多多面试必问项之List实现类:LinkedList
  3. abb限位开关已打开drv1_广告雕刻机限位开关触发
  4. 简述原型模型的特点_3D打印硅胶复模手板的步骤和特点有哪些
  5. gpl可以商用吗_一文看懂开源许可证,能不能商用再也不抓瞎
  6. iphone查看删除的短信_手机资讯:iPhone手机可以批量删除短信吗如何操作
  7. android 导航 美国,变美了 Android N或用全新虚拟导航按键
  8. PHP秒杀截流原理,节流阀和去抖动的基本实现方法介绍
  9. linux退出lftp命令,lftp命令使用
  10. leetcode双指针合集