C/C++,动态 DP 问题的计算方法与源程序

news2024/11/26 2:07:18

1 文本格式

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int maxn = 500010;
const int INF = 0x3f3f3f3f;

int Begin[maxn], Next[maxn], To[maxn], e, n, m;
int size[maxn], son[maxn], top[maxn], fa[maxn], dis[maxn], p[maxn], id[maxn], End[maxn];
int cnt, tot, a[maxn], f[maxn][2];

struct matrix {
    int g[2][2];

    matrix() { memset(g, 0, sizeof(g)); }

    matrix operator*(const matrix& b) const  
    {
        matrix c;
        for (int i = 0; i <= 1; i++)
            for (int j = 0; j <= 1; j++)
                for (int k = 0; k <= 1; k++)
                    c.g[i][j] = max(c.g[i][j], g[i][k] + b.g[k][j]);
        return c;
    }
} Tree[maxn], g[maxn]; 

inline void PushUp(int root) {
    Tree[root] = Tree[root << 1] * Tree[root << 1 | 1];
}

inline void Build(int root, int l, int r) {
    if (l == r) {
        Tree[root] = g[id[l]];
        return;
    }
    int Mid = l + r >> 1;
    Build(root << 1, l, Mid);
    Build(root << 1 | 1, Mid + 1, r);
    PushUp(root);
}

inline matrix Query(int root, int l, int r, int L, int R) {
    if (L <= l && r <= R) return Tree[root];
    int Mid = l + r >> 1;
    if (R <= Mid) return Query(root << 1, l, Mid, L, R);
    if (Mid < L) return Query(root << 1 | 1, Mid + 1, r, L, R);
    return Query(root << 1, l, Mid, L, R) *
        Query(root << 1 | 1, Mid + 1, r, L, R);
}

inline void Modify(int root, int l, int r, int pos) {
    if (l == r) {
        Tree[root] = g[id[l]];
        return;
    }
    int Mid = l + r >> 1;
    if (pos <= Mid)
        Modify(root << 1, l, Mid, pos);
    else
        Modify(root << 1 | 1, Mid + 1, r, pos);
    PushUp(root);
}

inline void Update(int x, int val) {
    g[x].g[1][0] += val - a[x];
    a[x] = val;
    while (x) {
        matrix last = Query(1, 1, n, p[top[x]], End[top[x]]);
        Modify(1, 1, n,            p[x]);
        matrix now = Query(1, 1, n, p[top[x]], End[top[x]]);
        x = fa[top[x]];
        g[x].g[0][0] +=
            max(now.g[0][0], now.g[1][0]) - max(last.g[0][0], last.g[1][0]);
        g[x].g[0][1] = g[x].g[0][0];
        g[x].g[1][0] += now.g[0][0] - last.g[0][0];
    }
}

inline void add(int u, int v) {
    To[++e] = v;
    Next[e] = Begin[u];
    Begin[u] = e;
}

inline void DFS1(int u) {
    size[u] = 1;
    int Max = 0;
    f[u][1] = a[u];
    for (int i = Begin[u]; i; i = Next[i]) {
        int v = To[i];
        if (v == fa[u]) continue;
        dis[v] = dis[u] + 1;
        fa[v] = u;
        DFS1(v);
        size[u] += size[v];
        if (size[v] > Max) {
            Max = size[v];
            son[u] = v;
        }
        f[u][1] += f[v][0];
        f[u][0] += max(f[v][0], f[v][1]);
    }
}

inline void DFS2(int u, int t) {
    top[u] = t;
    p[u] = ++cnt;
    id[cnt] = u;
    End[t] = cnt;
    g[u].g[1][0] = a[u];
    g[u].g[1][1] = -INF;
    if (!son[u]) return;
    DFS2(son[u], t);
    for (int i = Begin[u]; i; i = Next[i]) {
        int v = To[i];
        if (v == fa[u] || v == son[u]) continue;
        DFS2(v, v);
        g[u].g[0][0] += max(f[v][0], f[v][1]);
        g[u].g[1][0] += f[v][0];
    }
    g[u].g[0][1] = g[u].g[0][0];
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for (int i = 1; i <= n - 1; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        add(u, v);
        add(v, u);
    }
    dis[1] = 1;
    DFS1(1);
    DFS2(1, 1);
    Build(1, 1, n);
    for (int i = 1; i <= m; i++) {
        int x, val;
        scanf("%d%d", &x, &val);
        Update(x, val);
        matrix ans = Query(1, 1, n, 1, End[1]);
        printf("%d\n", max(ans.g[0][0], ans.g[1][0]));
    }
    return 0;
}

2 代码格式

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int maxn = 500010;
const int INF = 0x3f3f3f3f;

int Begin[maxn], Next[maxn], To[maxn], e, n, m;
int size[maxn], son[maxn], top[maxn], fa[maxn], dis[maxn], p[maxn], id[maxn], End[maxn];
int cnt, tot, a[maxn], f[maxn][2];

struct matrix {
	int g[2][2];

	matrix() { memset(g, 0, sizeof(g)); }

	matrix operator*(const matrix& b) const  
	{
		matrix c;
		for (int i = 0; i <= 1; i++)
			for (int j = 0; j <= 1; j++)
				for (int k = 0; k <= 1; k++)
					c.g[i][j] = max(c.g[i][j], g[i][k] + b.g[k][j]);
		return c;
	}
} Tree[maxn], g[maxn]; 

inline void PushUp(int root) {
	Tree[root] = Tree[root << 1] * Tree[root << 1 | 1];
}

inline void Build(int root, int l, int r) {
	if (l == r) {
		Tree[root] = g[id[l]];
		return;
	}
	int Mid = l + r >> 1;
	Build(root << 1, l, Mid);
	Build(root << 1 | 1, Mid + 1, r);
	PushUp(root);
}

inline matrix Query(int root, int l, int r, int L, int R) {
	if (L <= l && r <= R) return Tree[root];
	int Mid = l + r >> 1;
	if (R <= Mid) return Query(root << 1, l, Mid, L, R);
	if (Mid < L) return Query(root << 1 | 1, Mid + 1, r, L, R);
	return Query(root << 1, l, Mid, L, R) *
		Query(root << 1 | 1, Mid + 1, r, L, R);
}

inline void Modify(int root, int l, int r, int pos) {
	if (l == r) {
		Tree[root] = g[id[l]];
		return;
	}
	int Mid = l + r >> 1;
	if (pos <= Mid)
		Modify(root << 1, l, Mid, pos);
	else
		Modify(root << 1 | 1, Mid + 1, r, pos);
	PushUp(root);
}

inline void Update(int x, int val) {
	g[x].g[1][0] += val - a[x];
	a[x] = val;
	while (x) {
		matrix last = Query(1, 1, n, p[top[x]], End[top[x]]);
		Modify(1, 1, n,			p[x]);
		matrix now = Query(1, 1, n, p[top[x]], End[top[x]]);
		x = fa[top[x]];
		g[x].g[0][0] +=
			max(now.g[0][0], now.g[1][0]) - max(last.g[0][0], last.g[1][0]);
		g[x].g[0][1] = g[x].g[0][0];
		g[x].g[1][0] += now.g[0][0] - last.g[0][0];
	}
}

inline void add(int u, int v) {
	To[++e] = v;
	Next[e] = Begin[u];
	Begin[u] = e;
}

inline void DFS1(int u) {
	size[u] = 1;
	int Max = 0;
	f[u][1] = a[u];
	for (int i = Begin[u]; i; i = Next[i]) {
		int v = To[i];
		if (v == fa[u]) continue;
		dis[v] = dis[u] + 1;
		fa[v] = u;
		DFS1(v);
		size[u] += size[v];
		if (size[v] > Max) {
			Max = size[v];
			son[u] = v;
		}
		f[u][1] += f[v][0];
		f[u][0] += max(f[v][0], f[v][1]);
	}
}

inline void DFS2(int u, int t) {
	top[u] = t;
	p[u] = ++cnt;
	id[cnt] = u;
	End[t] = cnt;
	g[u].g[1][0] = a[u];
	g[u].g[1][1] = -INF;
	if (!son[u]) return;
	DFS2(son[u], t);
	for (int i = Begin[u]; i; i = Next[i]) {
		int v = To[i];
		if (v == fa[u] || v == son[u]) continue;
		DFS2(v, v);
		g[u].g[0][0] += max(f[v][0], f[v][1]);
		g[u].g[1][0] += f[v][0];
	}
	g[u].g[0][1] = g[u].g[0][0];
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
	for (int i = 1; i <= n - 1; i++) {
		int u, v;
		scanf("%d%d", &u, &v);
		add(u, v);
		add(v, u);
	}
	dis[1] = 1;
	DFS1(1);
	DFS2(1, 1);
	Build(1, 1, n);
	for (int i = 1; i <= m; i++) {
		int x, val;
		scanf("%d%d", &x, &val);
		Update(x, val);
		matrix ans = Query(1, 1, n, 1, End[1]);
		printf("%d\n", max(ans.g[0][0], ans.g[1][0]));
	}
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1305740.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

推荐开源项目-网络应用协议框架Socket.D

基于事件和语义消息流的网络应用协议 Socket.D 0 代码仓库地址1 该开源项目特点2 项目结构3 核心理念-协议帧Frame4 结束语 0 代码仓库地址 https://gitee.com/noear/socketd 1 该开源项目特点 代码风格优雅文档说明齐全测试用例非常人性化上手快&#xff0c;代码用例很多代…

基于双树复小波变换和稀疏表示的多光谱和彩色图像融合算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 双树复小波变换原理 4.2 稀疏表示原理 4.3 基于双树复小波变换和稀疏表示的图像融合算法 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序…

Appium 自动化自学篇 —— 初识Appium自动化!

Appium 简介 随着移动终端的普及&#xff0c;手机应用越来越多&#xff0c;也越来越重要。而作为测试 的我们也要与时俱进&#xff0c;努力学习手机 App 的相关测试&#xff0c;文章将介绍手机自动化测试框架 Appium 。 那究竟什么是 Appium 呢? 接下来我们一起来学习PythonS…

Spring 的设计思想、创建和使用、Bean 作用域和生命周期

文章目录 Spring 设计思想Spring 是什么&#xff1f;什么是 IoC&#xff1f; Spring 创建和使用创建 Spring 项目注册 Bean 对象获取并使用 Bean 对象 Spring 更方便地存储和读取对象配置文件使用注解使用类注解使用方法注解 获取 Bean 对象属性注入Setter 注入构造方法注入Res…

基于FPGA的视频接口之高速IO(光纤)

简介 对于高速IO口配置光纤,现在目前大部分开发板都有配置,且也有说明,在此根据自己的工作经验以及对于各开发板的说明归纳 通过高速IO接口,以及硬件配置,可以实现对于光纤的收发功能,由于GTX的速率在500Mbs到10Gbps之间,但通道高速io可配置光纤10G硬件,物理通完成,则…

Unity 修改游戏对象的旋转角度Rotation的方法

在Unity中要修改游戏对象中的旋转角度&#xff0c;即下图中的Rotation: 有三个方法&#xff1a; 1、 使用欧拉角&#xff08;Euler Angles&#xff09;&#xff1a;欧拉角是一组表示旋转的三个角度值&#xff08;绕X轴的旋转、绕Y轴的旋转和绕Z轴的旋转&#xff09;。 transf…

Unity光照模型实践

光照作为3D渲染中最重要的部分之一&#xff0c;如何去模拟真实环境的光照是重要的研究内容&#xff0c;但是现实环境光照过于复杂&#xff0c;有很多经典好用的光照模型去近似真实光照。 根据基础的Phong模型 最终某个点的结果为 环境光Ambient 漫反射光Diffuse 高光Specula…

Hadoop高可用(主备切换)---配合Zookeeper

1. Hadoop高可用(Hadoop High Availability)概述 HA(High Available), 高可用&#xff0c;是保证业务连续性的有效解决方案&#xff0c;一般有两个或两个以上的节点&#xff0c;分为活动节点&#xff08;Active&#xff09;及备用节点&#xff08;Standby&#xff09;。通常把…

Mendix 创客访谈录|合作伙伴谈Mendix对销售团队的业务价值

本期创客 段晓科 适途科技 咨询中心负责人 大家好&#xff0c;我叫段晓科&#xff0c;非软件开发专业&#xff0c;拥有多年制造行业数字化解决方案经验&#xff0c;擅长从0到1 的产品构建和产品落地服务。 目前任职于适途科技&#xff0c;自2021年3月至今负责Mendix低代码平台…

sonar扫描代码用法

1 mvn的setting配置文件中配置如下 其中sonar.host.url是本地或者服务器上自己安装的sonar <pluginGroups><pluginGroup>org.sonarsource.scanner.maven</pluginGroup></pluginGroups><profile><id>sonar</id><activation>&l…

boost graph之基础

结构 属性相关 #mermaid-svg-PZQvKfbwNSnyXO9g {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-PZQvKfbwNSnyXO9g .error-icon{fill:#552222;}#mermaid-svg-PZQvKfbwNSnyXO9g .error-text{fill:#552222;stroke:#5522…

文心一言 VS 讯飞星火 VS chatgpt (155)-- 算法导论12.3 2题

二、用go语言&#xff0c;假设通过反复向一棵树中插人互不相同的关键字来构造一棵二叉搜索树。证明&#xff1a;在这棵树中查找关键字所检查过的结点数目等于先前插入这个关键字所检查的结点数目加 1。 文心一言&#xff1a; 为了证明这个结论&#xff0c;我们可以使用二叉搜…

【代码随想录】刷题笔记Day34

前言 考过概率论&#xff0c;发过一场烧&#xff0c;兜兜转转又一月&#xff0c;轻舟已撞万重山&#xff0c;赶紧刷题 贪心算法理论基础 贪心的本质&#xff1a;局部最优→全局最优无套路&#xff0c;常识性推导 举反例 455. 分发饼干 - 力扣&#xff08;LeetCode&#xf…

Python (六) 绘图

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

故障注入测试有哪些多重作用?

在软件开发的世界中&#xff0c;保证系统的鲁棒性和稳定性至关重要。为了应对各种潜在的故障和异常情况&#xff0c;测试团队采用了各种测试方法&#xff0c;其中之一就是故障注入测试。这种测试方法的目标是有目的地向系统引入故障&#xff0c;以评估系统在面对异常情况时的表…

在pom.xml中添加maven依赖,但是类里面import导入的时候报错

问题&#xff1a; Error:(27, 8) java: 类TestKuDo是公共的, 应在名为 TestKuDo.java 的文件中声明 Error:(7, 23) java: 程序包org.apache.kudu不存在 Error:(8, 23) java: 程序包org.apache.kudu不存在 Error:(9, 23) java: 程序包org.apache.kudu不存在 Error:(10, 30) jav…

【VRTK】【VR开发】【Unity】11-甩臂移动

课程配套学习资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【概述】 除了一般的移动能力,VRTK还提供更为沉浸的甩臂移动。 【设定摇杆输入中间件】 在Hierarchy中展开Button Input Actions,其下生成两个新的空子对象…

震撼!这个Python模块竟然能自动修复代码!

说到Python的强大的地方&#xff0c;那真的是太多了&#xff0c;优雅、简洁、丰富且强大的第三方库、开发速度快&#xff0c;社区活跃度高等&#xff0c;所以才使得Python才会如此的受欢迎。 今天给大家介绍一个特别暴力的Python库: FuckIt&#xff0c; 1、FuckIt介绍 FuckI…

接口管理——Swagger

Swagger是一个用于设计、构建和文档化API的工具集。它包括一系列工具&#xff0c;如Swagger Editor&#xff08;用于编辑Swagger规范&#xff09;、Swagger UI&#xff08;用于可视化API文档&#xff09;和Swagger Codegen&#xff08;用于根据API定义生成客户端库、server stu…

文件搜索项目演示

演示功能搜索功能1&#xff1a;根据文件名搜索2&#xff1a;根据文件路径搜索3&#xff1a;根据文件名拼音(全拼、首拼)搜索 选择更新目录功能自动初始化和定时更新功能程序文件项目知识介绍 演示功能 搜索功能 1&#xff1a;根据文件名搜索 2&#xff1a;根据文件路径搜索 3…