Luogu P4719 动态dp

CodeForces1046B Hyperspace Highways 传送门 题意: N个点,M条边,每一个环上的点两两有边相连。q次询问两点间最短距离。 题解: 构造圆方树,那么两点间距离感性认知一下就可以发现是树上两点间距离的一半。然后 dist(u,v)=(dep[u]+dep[v]-2*dep[lca])/2即可。 继续存板子。 代码: #include<cstdio> #include<algorithm> #define maxn... 阅读详情

传送门

题解:
日常的写不动题,存板
假设这玩意不是动态的:
设 f [ i ] [ 0 / 1 ] f[i][0/1] f[i][0/1]为第i个点不选/选的答案。那么 f [ i ] [ 0 ] = ∑ max ⁡ ( f [ j ] [ 0 ] , f [ j ] [ 1 ] ) , f [ i ] [ 1 ] = ∑ f [ j ] [ 0 ] + v [ i ] . f[i][0]=\sum\max(f[j][0],f[j][1]),f[i][1]=\sum f[j][0]+v[i]. f[i][0]=∑max(f[j][0],f[j][1]),f[i][1]=∑f[j][0]+v[i].
然后修改一个点的权值最多对上面的值有影响。
然后再设 g [ i ] [ 0 / 1 ] g[i][0/1] g[i][0/1]为只考虑轻儿子的dp值。
于是 f [ i ] [ 0 ] = max ⁡ ( f [ s o n ] [ 0 ] , f [ s o n ] [ 1 ] ) + g [ i ] [ 0 ] , f [ i ] [ 1 ] = f [ s o n ] [ 0 ] + g [ i ] [ 1 ] . f[i][0]=\max(f[son][0],f[son][1])+g[i][0],f[i][1]=f[son][0]+g[i][1]. f[i][0]=max(f[son][0],f[son][1])+g[i][0],f[i][1]=f[son][0]+g[i][1].
然后利用人类智慧可以定义乘法为加法,定义加法为取max,搞出一个矩阵:
( f [ i ] [ 0 ] f [ i ] [ 1 ] ) = ( g [ i ] [ 0 ] g [ i ] [ 0 ] g [ i ] [ 1 ] − ∞ ) × ( f [ s o n ] [ 0 ] f [ s o n ] [ 1 ] ) \begin{pmatrix} f[i][0] \\ f[i][1] \end{pmatrix}=\begin{pmatrix} g[i][0] &amp; g[i][0] \\ g[i][1] &amp; -\infty \end{pmatrix}\times \begin{pmatrix} f[son][0] \\ f[son][1] \end{pmatrix} (f[i][0]f[i][1]​)=(g[i][0]g[i][1]​g[i][0]−∞​)×(f[son][0]f[son][1]​)
然后就可以树剖再上个线段树维护了。修改的时候改改重链f值改改链顶g值就行了。
不知道为毛这道题右下角取0都能过

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 100005
using namespace std;
int n,m,a[maxn],dep[maxn],fa[maxn],top[maxn],son[maxn],siz[maxn],tid[maxn],ed[maxn],rnk[maxn],ccnt,g[maxn][2];
struct node { int v; node *nxt; } edge[maxn*2],*head[maxn],*ncnt;
struct mat { int f[2][2]; } tree[maxn*4],val[maxn];
mat operator * (mat a,mat b)
{
    mat c;
    memset(c.f,0,sizeof(c.f));
    for(int k=0;k<2;k++)
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++) c.f[i][j]=max(c.f[i][j],a.f[i][k]+b.f[k][j]);
    return c;
}
void addedge(int u,int v)
{
    ncnt++;
    ncnt->v=v,ncnt->nxt=head[u];
    head[u]=ncnt;
}
void dfs1(int u,int f,int d)
{
    dep[u]=d,fa[u]=f,siz[u]=1,g[u][1]=a[u];
    for(node *p=head[u];p;p=p->nxt)
    {
        int v=p->v;
        if(v==f) continue;
        dfs1(v,u,d+1); siz[u]+=siz[v];
        if(siz[v]>siz[son[u]]) son[u]=v;
        g[u][0]+=max(g[v][0],g[v][1]),g[u][1]+=g[v][0];
    }
}
void dfs2(int u,int tp)
{
    tid[u]=++ccnt,rnk[ccnt]=u,top[u]=tp;
    if(!son[u]) { ed[u]=u; return; }
    dfs2(son[u],tp); ed[u]=ed[son[u]];
    for(node *p=head[u];p;p=p->nxt)
    {
        int v=p->v;
        if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
    }
}
void Build(int i,int l,int r)
{
    if(l==r)
    {
        int u=rnk[l],g0=0,g1=a[u];
        for(node *p=head[u];p;p=p->nxt)
        {
            int v=p->v;
            if(v!=fa[u]&&v!=son[u]) g0+=max(g[v][0],g[v][1]),g1+=g[v][0];
        }
        tree[i].f[0][0]=tree[i].f[0][1]=g0,tree[i].f[1][0]=g1;
        val[l]=tree[i];
        return;
    }
    int mid=(l+r)>>1;
    Build(i<<1,l,mid); Build(i<<1|1,mid+1,r);
    tree[i]=tree[i<<1]*tree[i<<1|1];
}
mat Query(int i,int l,int r,int ql,int qr)
{
    if(ql<=l&&r<=qr) return tree[i];
    int mid=(l+r)>>1;
    if(qr<=mid) return Query(i<<1,l,mid,ql,qr);
    else if(ql>mid) return Query(i<<1|1,mid+1,r,ql,qr);
    return Query(i<<1,l,mid,ql,qr)*Query(i<<1|1,mid+1,r,ql,qr);
}
void Modify(int i,int l,int r,int p)
{
    if(l==r) { tree[i]=val[l]; return; }
    int mid=(l+r)>>1;
    if(p<=mid) Modify(i<<1,l,mid,p);
    else Modify(i<<1|1,mid+1,r,p);
    tree[i]=tree[i<<1]*tree[i<<1|1];
}
void Modify(int u,int x)
{
    val[tid[u]].f[1][0]+=x-a[u]; a[u]=x;
    while(u)
    {
        mat la=Query(1,1,n,tid[top[u]],tid[ed[u]]);
        Modify(1,1,n,tid[u]);
        mat cur=Query(1,1,n,tid[top[u]],tid[ed[u]]);
        u=fa[top[u]];
        val[tid[u]].f[0][0]+=max(cur.f[0][0],cur.f[1][0])-max(la.f[0][0],la.f[1][0]);
        val[tid[u]].f[0][1]=val[tid[u]].f[0][0];
        val[tid[u]].f[1][0]+=cur.f[0][0]-la.f[0][0];
    }
}
int main()
{
    scanf("%d%d",&n,&m); ncnt=&edge[0];
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        addedge(u,v); addedge(v,u);
    }
    dfs1(1,0,1); dfs2(1,1);
    Build(1,1,n);
    while(m--)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        Modify(x,y);
        mat t=Query(1,1,n,tid[1],tid[ed[1]]);
        printf("%d\n",max(t.f[0][0],t.f[1][0]));
    }
}
STM32 烧录报错Invalid ROM Table 阅读详情

相关推荐

毫米波雷达之CFAR 目标检测

恒虚警率(CFAR)算法是一种广泛应用于雷达目标检测的算法,其主要目 标是减少由于杂波与回波之间强度不对称而引起的误报,以确保相对恒定的虚警 率。如图 3.4(a)所示,表示由距离单元组成的一维数据。在待测单元 D 周围选 择若干个背景杂波功率的蓝色单元构成参考滑窗,称为参考单元;而待测单元 D 相邻的若干个不用于背景估计的单元则称为保护单元。当参考单元和保护单元的 维度从一维扩展到二维时,相应的 CFAR 检测由一维 CFAR 演变为二维 CFAR 以处理参考窗口,如图 3.4 (b)所示。

m0_56120826的博客 4921

luogu P4719 【模板】动态dp

背景: NOIPNOIPNOIP的坑。 现在开始学…(坑) 题目传送门: https://www.luogu.org/problemnew/show/P4719 题意: 求动态的树上最大独立集(就是选出若干个点,使得这些点中两两没有连边,并且权值和最大)。 思路: 考虑常规做法。 f[i][0]f[i][0]f[i][0]表示以iii点为根的子树,不选iii点的最大独立集的和; f[i...

zsyz_ZZY的博客 421

深入解析AXI-Stream协议中的TVALID与TREADY握手时序

本文深入解析AXI-Stream协议中TVALID与TREADY的握手时序,通过实际案例和代码示例详细说明三种典型握手场景及其应用。文章还探讨了常见握手失败案例的解决方法,并介绍了TLAST、TKEEP等高级信号的使用技巧,帮助开发者优化FPGA设计中的数据传输效率。

weixin_29200485的博客 341

Luogu P4719 【模板】动态 DP

题目大意 %  给定一棵 nnn 个点的树,点带点权。有 mmm 次操作,每次操作给定 x,yx,yx,y,表示修改点 xxx 的权值为 yyy,输出每次修改后树的最大权独立集大小。 %  数据范围 1⩽n,m⩽1051\leqslant n,m\leqslant 10^51⩽n,m⩽105 题解 %   首先如果不考虑修改操作,很容易想到动态规划,首先是定义 %   fu,0f_{u,0}fu...

linjiayang2016的博客 194

国内优秀MES开源框架

一套springboot 开源框架 代码标准规范化。 界面展示 演示地址 http://wangziyangmes.pzzd.xyz 用户名admin 密码123 系统管理 工艺管理 计划管理 物料管理 *用户管理* *工艺路线管理* 工单下达...

q707231019的博客 2万+

LVGL v9的lv_scale控件实战:5分钟打造动态仪表盘(附完整代码)

本文详细介绍了LVGL v9中lv_scale控件的实战应用,通过5个关键步骤快速打造动态仪表盘。文章涵盖核心特性解析、代码实现、样式定制及性能优化,适用于工业HMI、智能家居等场景,并附完整代码示例。

gin88的博客 262

luogu P4719 【模板】动态 DP 矩阵乘法_LCT

luogu P4719 【模板】动态 DP 矩阵乘法_LCT Code: // luogu-judger-enable-o2 //Dynamic DP with LCT #include<bits/stdc++.h> #define ll long long #define setIO(s) freopen(s".in...

EM LGH 239

Cadence OrCAD: 层次化设计 Hierarchical Design

详细介绍OrCAD的原理图层次化设计方法。

Fantasy237的博客 1万+

[Luogu P4719] 【模板】动态dp

洛谷传送门 题目描述 给定一棵nnn个点的树,点带点权。 有mmm次操作,每次操作给定x,yx,yx,y,表示修改点xxx的权值为yyy。 你需要在每次操作之后求出这棵树的最大权独立集的权值大小。 输入输出格式 输入格式: 第一行,n,mn,mn,m,分别代表点数和操作数。 第二行,V1,V2,...,VnV_1,V_2,...,V_nV1​,V2​,...,Vn​,代表nnn个点的权值。 接下来...

LPA的博客 342

老电脑续命神器:Windows 11 26H1 精简游戏版,帧率稳定无压力!(Win11 26H1 极致精简游戏版(3.17G):装完只占 8G 内存,Ultra CPU 性能拉满)

旧电脑福音也能安装windows11畅玩游戏🎮:文章分享一款 Windows 11 26H1 精简游戏版,仅 3.17G、C 盘占用 8G,开机进程约 50 个,内存占用 1.4G,内置游戏优化与运行库,支持离线安装、跳过 TPM 检测,让老电脑也能畅玩 3A 游戏和办公娱乐 🚀。

XiaoqiangClub的博客 1064

解锁RK1126与SC132GS摄像头适配密码:技术与代码全解析

本文详细介绍了瑞芯微RK1126芯片与SC132GS摄像头的适配方法。首先分析了RK1126的四核Cortex-A7处理器、Mali-T860 GPU等硬件特性,以及SC132GS的130万像素、全局快门等技术参数。重点阐述了基于MIPI CSI接口的硬件连接原理和基于V4L2框架的软件驱动设计,并提供了完整的初始化、数据采集和图像处理代码实现。针对常见连接和图像质量问题给出了解决方案,展现了该组合在智能安防、工业检测等领域的应用潜力,为开发者提供了实用的技术参考。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 1503

【Luogu】 P4719 【模板】“动态 DP“&动态树分治

所以最后的操作步骤就是再线段树上维护区间转移矩阵的乘积,修改时每次修改重链的头的父亲的转移矩阵,新的转移矩阵可以通过线段树上查询得到。考虑每次修改时,只会更改当前点到根的路径上的。于是根据以下 3 个性质,我们考虑使用重链剖分。既然提到用矩乘维护转移,那么考虑对于每一个。,维护转移矩阵表示不包括重儿子的转移矩阵。,这仍然是满足结合律的(但不满足交换律)是否选的最大权独立集的权值大小。值,所以可以考虑快速维护这个。表示以 1 为根的树,在。合并 2 棵子树时可以。,这里重定义矩阵乘法为。

djx2021的博客 292

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

luogu P4719 【模板】动态 DP 矩阵乘法 + LCT

方法二:LCT+矩阵乘法 上文中,我们用线段树来维护重链上的各种矩阵转移. 第二种方法是将树链剖分替换为动态树. 我们知道,矩阵乘法 $\begin{bmatrix} F_{u,0} & F_{u,0}\\ F_{u,1} & -\infty \end{bmatrix}\times\begin{bmatrix} F_{i,0}\\F_{i,1} \end{bmatri...

weixin_30496431的博客 136

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

luogu P4719 【模板】动态 DP (LCT版)

方法二:LCT+矩阵乘法 上文中,我们用线段树来维护重链上的各种矩阵转移. 第二种方法是将树链剖分替换为动态树. 我们知道,矩阵乘法 $\begin{bmatrix} F_{u,0} & F_{u,0}\\ F_{u,1} & -\infty \end{bmatrix}\times\begin{bmatrix} F_{i,0}\\F_{i,1} \end{b...

EM LGH 127

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

【luogu P4719】【模板】“动态 DP“&动态树分治(DDP)(重链剖分)(线段树)

给你一棵树,点带权,每次操作修改点权,要你求最大权独立集的权值大小。

欢迎您的光顾awa 711

[复习]动态dp

[复习]动态dp 你还是可以认为我原来写的动态dp就是在扯蛋。 [Luogu4719]【模板】动态dp 首先作为一个\(dp\)题,我们显然可以每次修改之后都进行暴力\(dp\),设\(f[i][0/1]\)表示当前考虑\(i\)及其子树内的点,当前这个点是选还是不选时能够得到的最大权值,那么我们可以得到转移:\(f[i][0]+=\max\{f[v][0],f[v][1]\},f[i][1]+=...

weixin_30443813的博客 92

luogu4719+NOIP2018day2T3 动态dp

在进入正文以前,我想先哭一下。 嘤嘤嘤嘤嘤嘤嘤 嘤嘤嘤嘤嘤嘤嘤 嘤嘤嘤我嘤嘤嘤 嘤嘤嘤嘤嘤嘤嘤 嘤嘤嘤嘤嘤嘤嘤 事实上在NOIP2018以前,我看到过动态dp的课件,然后觉得看起来很有意思。 但是我竟然没有仔细去看!没有仔细去看!。。。 内心:NOIP肯定不会考这种东西呀orz......(flag) 然后NOIP2018day2T3就是动态dp裸题。 呵呵呵呵呵呵呵。。。 ...

shiveringkonnyaku的博客 364

【Luogu】 P5024 [NOIP2018 提高组] 保卫王国

中的方法解决,但可以考虑更多的做法。的其他儿子转移而来的转移矩阵。首先这道题带修改的版本是。这一题不带修改,也可以用。每次修改只会修改两个点。这样定义有 2 个好处。

djx2021的博客 255

[学习笔记]动态动态规划/动态DP/DDP

概述 \(DDP\)是指一类需要支持修改的\(DP\)问题,常见的主要是带修树形\(DP\),可以用树链剖分结合矩阵乘法优化修改的复杂度 详解 从例题来分析:洛谷P4719 题目大意:给出\(n\)个点的树,每个点有点权,共\(m\)次操作,每次修改一个点的点权,求每次修改后树的最大权独立集的权值大小 \(n, m \le 1e5\) 如果不带修改,容易想到设\(f_{u, 0/1}\)来表...

weixin_30278311的博客 176

浅谈动态dp

动态DP主要用来解决对蒟蒻们(比如我)本来比较友好的树上DP问题(静态树),但是被一些毒瘤出题人(惊现lxl!)硬套上了对点权的修改操作,比如洛谷上的这道题(P4719 【模板】“动态 DP”&动态树分治): 给定一棵 nnn 个点的树,点带点权。有 mmm 次操作,每次操作给定 x,yx,yx,y,表示修改点 xxx 的权值为 yyy。你需要在每次操作之后求出这棵树的最大权独立集的权值大小。 首先概述一下独立集的概念:对于集合中的任意两元素 u,vu,vu,v ,满足:uuu 与 vvv 间没

Bestlan6626的博客 254

[luogu 4719][模板]动态dp

传送门 Solution \(f_{i,0}\) 表示以i节点为根的子树内,不选i号节点的最大独立集 \(f_{i,1}\)表示以i节点为根的子树内,选i号节点的最大独立集 \(g_{i,0}\) 表示以i节点为根的子树内,不选i号节点,不算它的重节点子树的最大独立集 \(g_{i,1}\) 表示以i节点为根的子树内,选i号节点,不算它的重节点子树的最大独立集 把矩阵乘法的加法改成m...

weixin_30480583的博客 91

luogu P5024 保卫王国

背景: NOIP2018NOIP2018NOIP2018的坑。 现在还是坑。 &amp;amp;amp;amp;amp;amp;lt;.br&amp;amp;amp;amp;amp;amp;gt; 题目传送门: https://www.luogu.org/problemnew/show/P5024 题意: 一棵树,要选一些覆盖所用的边。 特殊地,每一次询问都会硬性要求某两个点必须选或必须不选。 思路: 考虑常规做法。 f[i][0]f[i][0]f[

zsyz_ZZY的博客 336
上一篇: CodeChef MSTONES Milestones
下一篇: CodeForces1046B Hyperspace Highways
dogeding
博客等级 码龄10年 31粉丝 109原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值