• [动态dp][矩阵乘法][树链剖分][线段树] Luogu P4719 【模板】动态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
    ",max(ans.a[0][0],ans.a[1][0]));
    86 }
  • 相关阅读:
    自学Linux Shell5.2-shell内建命令history alias
    自学Linux Shell5.1-shell父子关系
    vue2.0 实现导航守卫(路由守卫)
    vue2.0 关于Vue实例的生命周期
    vue2.0 正确理解Vue.nextTick()的用途
    vue2.0 项目build后资源文件报错404的解决方案
    vue2.0 vetur插件提示 'v-for' directives require 'v-bind:key' directives 的解决办法
    vue2.0 微信oauth认证的正确调用位置
    vue2.0 样式表引入的方法 css sass less
    vue2.0 配置sass
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11365011.html
Copyright © 2020-2023  润新知