题目:https://www.luogu.org/problemnew/show/P4719

关于动态DP似乎有猫锟的WC2018论文,但找不见;还是算了。

http://immortalco.blog.uoj.ac/archive

动态DP大概就是求这样的问题。

把轻儿子对自己的转移值写进矩阵 g 里,重新定义一下乘法运算,自己的值矩阵 f 就是重儿子的 f 乘上自己的 g 了。

树剖的线段树维护区间内的那些 g 的连乘积,则从自己开始到自己所在重链的底端这一段的 g 连乘就是自己的 f 了(因为底端是叶子,所以本来该乘一个 f ,就和不乘一样了)。

修改的时候就是改一些 g 。自己如果在 x 的轻儿子里,则需要改一下 x 的 g 。一次会改 log  个 g 。

求答案就是 1 所在重链的连乘积。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #define ls Ls[cr]
  6. #define rs Rs[cr]
  7. using namespace std;
  8. const int N=1e5+,INF=1e9+;
  9. int n,m,w[N],hd[N],xnt,to[N<<],nxt[N<<],tot,Ls[N<<],Rs[N<<];
  10. int dfn[N],siz[N],son[N],rnk[N],dep[N],fa[N],top[N],bj[N],dp[N][];
  11. int Mx(int a,int b){return a>b?a:b;}
  12. struct Matrix{
  13. int a[][];
  14. Matrix(){a[][]=a[][]=a[][]=a[][]=-INF;}
  15. Matrix operator+ (const Matrix &b)const
  16. {
  17. Matrix c;
  18. for(int i=;i<=;i++)
  19. for(int k=;k<=;k++)
  20. for(int j=;j<=;j++)
  21. c.a[i][j]=Mx(c.a[i][j],a[i][k]+b.a[k][j]);
  22. return c;
  23. }
  24. }g[N],t[N<<];
  25. int rdn()
  26. {
  27. int ret=;bool fx=;char ch=getchar();
  28. while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
  29. while(ch>=''&&ch<='') ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
  30. return fx?ret:-ret;
  31. }
  32. void add(int x,int y){to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;}
  33. void dfs(int cr)
  34. {
  35. dep[cr]=dep[fa[cr]]+; siz[cr]=;
  36. for(int i=hd[cr],v;i;i=nxt[i])
  37. if((v=to[i])!=fa[cr])
  38. {
  39. fa[v]=cr; dfs(v);
  40. siz[cr]+=siz[v];
  41. siz[v]>siz[son[cr]]?son[cr]=v:;
  42. }
  43. }
  44. void dfsx(int cr)
  45. {
  46. dfn[cr]=++tot; rnk[tot]=cr;
  47. dp[cr][]=; dp[cr][]=w[cr];
  48. if(son[cr])
  49. {
  50. top[son[cr]]=top[cr];dfsx(son[cr]);
  51. dp[cr][]+=Mx(dp[son[cr]][],dp[son[cr]][]);
  52. dp[cr][]+=dp[son[cr]][];
  53. }
  54. g[cr].a[][]=g[cr].a[][]=;
  55. g[cr].a[][]=w[cr]; g[cr].a[][]=-INF;
  56. if(!son[cr]){ bj[top[cr]]=tot; return;}
  57. for(int i=hd[cr],v;i;i=nxt[i])
  58. if((v=to[i])!=fa[cr]&&v!=son[cr])
  59. {
  60. top[v]=v; dfsx(v);
  61. dp[cr][]+=Mx(dp[v][],dp[v][]); dp[cr][]+=dp[v][];
  62. g[cr].a[][]+=Mx(dp[v][],dp[v][]); g[cr].a[][]=g[cr].a[][];
  63. g[cr].a[][]+=dp[v][];
  64. }
  65. }
  66. void build(int l,int r,int cr)
  67. {
  68. if(l==r){t[cr]=g[rnk[l]];return;}
  69. int mid=l+r>>;
  70. ls=++tot; build(l,mid,ls);
  71. rs=++tot; build(mid+,r,rs);
  72. t[cr]=t[ls]+t[rs];
  73. }
  74. void updt(int l,int r,int cr,int p)
  75. {
  76. if(l==r){t[cr]=g[rnk[l]];return;}
  77. int mid=l+r>>;
  78. if(p<=mid)updt(l,mid,ls,p);
  79. else updt(mid+,r,rs,p);
  80. t[cr]=t[ls]+t[rs];
  81. }
  82. Matrix query(int l,int r,int cr,int L,int R)
  83. {
  84. if(l>=L&&r<=R)return t[cr];
  85. int mid=l+r>>;
  86. if(R<=mid)return query(l,mid,ls,L,R);
  87. if(mid<L) return query(mid+,r,rs,L,R);
  88. return query(l,mid,ls,L,R)+query(mid+,r,rs,L,R);
  89. }
  90. Matrix calc(int cr){ return query(,n,,dfn[cr],bj[cr]);}
  91. void cz(int x,int y)
  92. {
  93. g[x].a[][]+=y-w[x]; w[x]=y;
  94. Matrix k1=calc(top[x]); updt(,n,,dfn[x]); Matrix k2=calc(top[x]);
  95. while(fa[top[x]])
  96. {
  97. int d=fa[top[x]];
  98. g[d].a[][]+=Mx(k2.a[][],k2.a[][])-Mx(k1.a[][],k1.a[][]);
  99. g[d].a[][]=g[d].a[][];
  100. g[d].a[][]+=k2.a[][]-k1.a[][];
  101. x=d;
  102. k1=calc(top[x]); updt(,n,,dfn[x]); k2=calc(top[x]);
  103. }
  104. }
  105. int main()
  106. {
  107. n=rdn();m=rdn();
  108. for(int i=;i<=n;i++)w[i]=rdn();
  109. for(int i=,u,v;i<n;i++)
  110. {
  111. u=rdn(); v=rdn(); add(u,v); add(v,u);
  112. }
  113. dfs(); top[]=; dfsx(); tot=; build(,n,);//tot=1!!!!!!
  114. for(int i=,x,y;i<=m;i++)
  115. {
  116. x=rdn(); y=rdn(); cz(x,y);
  117. Matrix d=calc();
  118. printf("%d\n",Mx(d.a[][],d.a[][]));
  119. }
  120. return ;
  121. }

洛谷4719 【模板】动态dp的更多相关文章

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

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

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

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

  3. [luogu 4719][模板]动态dp

    传送门 Solution \(f_{i,0}\) 表示以i节点为根的子树内,不选i号节点的最大独立集 \(f_{i,1}\)表示以i节点为根的子树内,选i号节点的最大独立集 \(g_{i,0}\) 表 ...

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

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

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

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

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

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

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

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

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

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

  9. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

随机推荐

  1. WebSocket 的后记

    一个美好的概念可以让策划无比幼稚和疯狂, 比如 H5 改变世界呀,小程序替代 APP 呀,现在即时通信也被公司里的他们认为 so easy 了. 这很尴尬好吧,WebSocket(以下简称 ws) 的 ...

  2. poj 2828 Buy Tickets 【买票插队找位置 输出最后的位置序列+线段树】

    题目地址:http://poj.org/problem?id=2828 Sample Input 4 0 77 1 51 1 33 2 69 4 0 20523 1 19243 1 3890 0 31 ...

  3. Java线程池ExecutorService和CountDownLatch的小例子

    import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java ...

  4. vs+mysql+ef配置方法

    这次的项目用的是MySQL数据库,但是ADO.NET实体数据模型默认是不支持MySQL数据库的,本文档将介绍如何让VS ADO.NET实体数据模型支持MySQL. 一.安装插件 1.VS插件 mysq ...

  5. skynet中的各种锁

    最近读skynet c语言部分的源码,发现有好多锁的使用和gcc提供的一些原子操作.看到这些东西,对于我这个newbee来说实在有些hold不住.但为了了解并进一步掌握,还是决定好好分析一下.不足之处 ...

  6. 分开统计的sql写法

    DECLARE @StartDate DATETIME= '2017-10-13 00:00:00';DECLARE @EndDate DATETIME= '2017-11-13 23:00:00'; ...

  7. 如何用Qt写一个同一时间只能运行一个实例的应用程序

    http://blog.sina.com.cn/s/blog_6343941a0100nk2x.html 可以达到的目的: 1.应用只启动一个实例,依赖于QtNetwork模块 2.启动时向另一个实例 ...

  8. odl v2 driver

    networking-odl项目的目的/用途就是sync odl和neutron的资源数据库和状态 v1中对于每个neutron的资源操作都相应的调用odl restfu api来同步odl,但问题有 ...

  9. PHP error_get_last() 函数

    error_get_last() 函数返回最后发生的错误 返回了一个关联数组,描述了最后错误的信息,以该错误的 "type". "message"." ...

  10. hdu3605最大流

    题意:给n个人m个星球,每个人适不适合去某个星球,每个星球的最大容量,看能不能满足所有人能去一个星球 题解:可以看出如果直接建边,边的个数是1e5左右的,这样时间肯定会爆掉,那么我们考虑用二进制状态压 ...