ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[动态dp][矩阵乘法][树链剖分][线段树] Luogu P4719 【模板】动态dp

2019-08-16 17:01:28  阅读:225  来源: 互联网

标签:val 剖分 int mid son ldp 动态 dp


 

 

 题解

  • 动态dp模板题,矩阵乘法有所不同C=A*B=max(a[i][j]+b[j][k])

 

代码

 1 #include <cstdio>
 2 #include <iostream>
 3 using namespace std;
 4 const int N=1e5+1,inf=999999999;
 5 struct matrix
 6 {
 7     int a[3][3];
 8     void init() { for (int i=0;i<2;i++) for (int j=0;j<2;j++) a[i][j]=-inf; }
 9 }ans,last,front,T[N*4],val[N];
10 struct edge{ int to,from; }e[N*2];
11 struct Tree{ int size,id,fa,top,son,deep,end; }t[N*2];
12 int n,m,cnt,tot,ldp[N][2],dp[N][2],head[N],a[N],b[N];
13 void insert(int x,int y)
14 {
15     e[++cnt].to=y,e[cnt].from=head[x],head[x]=cnt;
16     e[++cnt].to=x,e[cnt].from=head[y],head[y]=cnt;
17 }
18 matrix mul(matrix a,matrix b)
19 {
20     matrix c; c.init();
21     for (int i=0;i<2;i++) for (int j=0;j<2;j++) for (int k=0;k<2;k++) c.a[i][j]=max(c.a[i][j],a.a[i][k]+b.a[k][j]);
22     return c;
23 }
24 void dfs1(int x,int fa)
25 {
26     t[x].deep=t[fa].deep+1,t[x].size=1,t[x].fa=fa;
27     for (int i=head[x];i;i=e[i].from) if (e[i].to!=fa) 
28     {
29         dfs1(e[i].to,x),t[x].size+=t[e[i].to].size;
30         if (t[e[i].to].size>t[t[x].son].size) t[x].son=e[i].to;
31     }
32 }
33 void dfs2(int x,int pre)
34 {
35     t[x].id=++tot,t[x].top=pre,b[tot]=x,t[pre].end=tot;
36     if (t[x].son) dfs2(t[x].son,pre);
37     for (int i=head[x];i;i=e[i].from) if (e[i].to!=t[x].fa&&e[i].to!=t[x].son) dfs2(e[i].to,e[i].to);
38 }
39 void dfs3(int x)
40 {
41     ldp[x][1]=a[x];
42     for (int i=head[x];i;i=e[i].from) if (e[i].to!=t[x].fa&&e[i].to!=t[x].son) dfs3(e[i].to),ldp[x][0]+=max(dp[e[i].to][1],dp[e[i].to][0]),ldp[x][1]+=dp[e[i].to][0];
43     dp[x][0]+=ldp[x][0],dp[x][1]+=ldp[x][1];
44     if (!t[x].son) return;
45     dfs3(t[x].son),dp[x][0]+=max(dp[t[x].son][1],dp[t[x].son][0]),dp[x][1]+=dp[t[x].son][0];
46 }
47 void build(int d,int l,int r)
48 {
49     if (l==r) { val[b[l]].a[0][0]=ldp[b[l]][0],val[b[l]].a[1][0]=ldp[b[l]][1],val[b[l]].a[0][1]=ldp[b[l]][0],val[b[l]].a[1][1]=-inf,T[d]=val[b[l]]; return; }
50     int mid=l+r>>1;
51     build(d*2,l,mid),build(d*2+1,mid+1,r),T[d]=mul(T[d*2],T[d*2+1]);
52 }
53 void updata(int d,int l,int r,int x)
54 {
55     if (l==r&&l==x) { T[d]=val[b[x]]; return; }
56     int mid=l+r>>1;
57     if (mid>=x) updata(d*2,l,mid,x); else updata(d*2+1,mid+1,r,x);
58     T[d]=mul(T[d*2],T[d*2+1]);
59 }
60 matrix query(int d,int l,int r,int L,int R)
61 {
62     if (l>=L&&r<=R) return T[d];
63     int mid=l+r>>1;
64     if (mid>=R) return query(d*2,l,mid,L,R);
65     if (mid<L) return query(d*2+1,mid+1,r,L,R);
66     return mul(query(d*2,l,mid,L,R),query(d*2+1,mid+1,r,L,R));
67 }
68 void change(int x,int y)
69 {
70     val[x].a[1][0]+=y-a[x],a[x]=y;
71     while (x!=0)
72     {
73         int now=t[x].top;
74         last=query(1,1,n,t[now].id,t[now].end),updata(1,1,n,t[x].id),front=query(1,1,n,t[now].id,t[now].end);
75         x=t[now].fa,val[x].a[0][0]+=max(front.a[0][0],front.a[1][0])-max(last.a[0][0],last.a[1][0]),val[x].a[0][1]=val[x].a[0][0],val[x].a[1][0]+=front.a[0][0]-last.a[0][0];
76     }
77 }
78 int main()
79 {
80     freopen("data.in","r",stdin);
81     scanf("%d%d",&n,&m);
82     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
83     for (int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),insert(x,y);
84     dfs1(1,0),dfs2(1,1),dfs3(1),build(1,1,n);
85     for (int i=1,x,y;i<=m;i++) scanf("%d%d",&x,&y),change(x,y),ans=query(1,1,n,t[1].id,t[1].end),printf("%d\n",max(ans.a[0][0],ans.a[1][0]));
86 }

 

标签:val,剖分,int,mid,son,ldp,动态,dp
来源: https://www.cnblogs.com/Comfortable/p/11365011.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有