其他分享
首页 > 其他分享> > [动态dp][矩阵乘法][树链剖分][线段树] Luogu P4719 【模板】动态dp

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

作者:互联网

 

 

 题解

 

代码

 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