CCF-CSP真题《202309-5 阻击》思路+ c++满分题解

news2024/11/28 8:27:32

 想查看其他题的真题及题解的同学可以前往查看:CCF-CSP真题附题解大全

试题编号:202309-5
试题名称:阻击
时间限制:2.0s
内存限制:512.0MB
问题描述:

问题描述

上回提到,西西艾弗岛下方有一个庞大的遗迹群,栖息着一种名为“阴阳龙”的神兽。然而隔壁的狄迪吉岛盯上了西西艾弗岛,决定发动一场战争,试图从遗迹群中掠夺有价值的宝物。由此,西西艾弗岛不得不陷入一场漫长的阻击战中,史称“阴阳龙阻击战”。

狄迪吉岛拥有胜过西西艾弗岛的科技实力和武装水平,西西艾弗岛很快发现形势不妙:全歼敌军似乎是不可能的,唯一的策略是凭借主场作战的优势和人海战术,尽可能给敌军带来损失,当敌军发现发动进攻的损失明显超过收益时,就会无趣而归。

具体而言,西西艾弗岛共有 n 座城市,有 n−1 条道路连接这些城市,使得所有城市之间均可以通过道路互相到达。容易发现,任意两座城市之间都有唯一一条不经过重复城市的路径。

由于缺乏城市巷战的实力,西西艾弗岛决定将防御重心放在道路上。在每条道路上均派遣了一定的军队防守,当敌军经过时对其发动阻击。虽然由于实力的差距,并不能阻止敌军通过道路,但仍然可以对敌军造成一定的损失。

然而,敌军具有更强的科技,可以趁机对道路附近的遗迹进行探索,并掠夺其中的宝物——这也正是敌军发动战争的意义所在。如此,敌军通过一条道路时,“发掘宝物的收益”w 和“受到阻击的损失”b 两个值是独立的。

西西艾弗岛事先在狄迪吉岛中安插了一系列间谍,得到的情报消息如下:敌军将选择西西艾弗岛的两座城市作为进攻的“起点”和“终点”,并派遣军队在进攻起点城市登陆,沿两座城市间唯一的路径进攻至终点城市。同时,间谍还背负着另外一个重要的使命:影响敌军对于起点和终点城市的决策,使得敌军受到的总损失尽可能大,其中“总损失”定义为敌军经过的每条道路上的“受到阻击的损失”减去“发掘宝物的收益”之和,即 总损失是路径上的每条边总损失=∑e是路径上的每条边(be−we)。

此外,遗迹中宝物的价值与所处的环境属性密切相关,而阴阳龙的“现身”会使得环境的阴阳属性发生变化,这会使得敌军通过现身位置处的某一条道路时“发掘宝物的收益”w 发生变化。

这样的“阴阳龙现身”事件共会发生 m 次,你的任务就是帮助间谍计算出在所有事件前及每次事件后,敌军对于起点和终点城市的决策应当怎样改变,以最大化敌军的总损失。

输入格式

从标准输入读入数据。

第 1 行,两个非负整数 n,m,分别表示西西艾弗岛的城市数和“阴阳龙现身”事件数。

接下来 n−1 行,每行 4 个非负整数 ui,vi,wi,bi,表示第 i 条道路连接城市 ui 和 vi,敌军在这条道路上“发掘宝物的收益”为 wi,“受到阻击的损失”为 bi。

接下来 m 行,每行 2 个非负整数 xi,yi,表示一次“阴阳龙现身”事件,使得第 xi 条道路的“发掘宝物的收益”变为 yi。

输出格式

输出到标准输出中。

输出 m+1 行,每行一个非负整数,分别表示在所有事件前及每次事件后,对敌军造成的最大总损失。

样例输入

5 3
1 2 6 4
2 3 2 1
3 4 5 3
3 5 8 5
3 2
4 3
1 1

样例输出

0
1
3
4

样例说明

在最初,由于敌人攻打每一条道路都会有正收益,因此间谍最好的策略就是将进攻起点和终点选为同一座城市,这样敌军的总损失为 0。

第 1 次事件后,间谍可以将进攻起点和终点分别选在城市 3 和 4,这样敌军的总损失为 3−2=1。

第 2 次事件后,间谍可以将进攻起点和终点分别选在城市 4 和 5,这样敌军的总损失为 (3−2)+(5−3)=3。

第 3 次事件后,间谍可以将进攻起点和终点分别选在城市 1 和 5,这样敌军的总损失为 (4−1)+(1−2)+(5−3)=4。

评测用例规模与约定

对于所有测试数据保证:2≤n≤105,0≤m≤105,1≤ui,vi≤n,1≤xi≤n−1,0≤wi,bi,yi≤109。

测试点编号n≤m≤特殊性质
12020
2300300
3∼430003000A
5∼630003000B
7∼930003000
101050A
111050B
121050
13∼15105105A
16∼18105105B
19∼21105105C
22∼25105105

特殊性质 A:ui=i,vi=i+1。

特殊性质 B:0≤wi,yi≤10^8≤bi。

特殊性质 C:保证任意两座城市均可在经过不超过 100 条道路的前提下互相到达。

真题来源:阻击

感兴趣的同学可以如此编码进去进行练习提交

c++满分题解:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
 
const int N = 1e5 + 8;
 
class segment{
    #define lson root << 1
    #define rson root << 1 | 1
    LL ans[N << 2];
    LL lsum[N << 2];
    LL rsum[N << 2];
    LL sum[N << 2];
 
    public:
    void popup(int root){
        ans[root] = max({ans[lson], ans[rson], rsum[lson] + lsum[rson]});
        lsum[root] = max(lsum[lson], sum[lson] + lsum[rson]);
        rsum[root] = max(rsum[rson], sum[rson] + rsum[lson]);
        sum[root] = sum[lson] + sum[rson];
    }
 
    void build(int root, int l, int r, vector<int>& a){
        if (l == r){
            ans[root] = (a[l] >= 0 ? a[l] : 0);
            lsum[root] = (a[l] >= 0 ? a[l] : 0);
            rsum[root] = (a[l] >= 0 ? a[l] : 0);
            sum[root] = a[l];
            return;
        }
        int mid = (l + r) >> 1;
        build(lson, l, mid, a);
        build(rson, mid + 1, r, a);
        popup(root);
    }
 
    void update(int root, int l, int r, int pos, int val){
        if (l == r){
            ans[root] = (val >= 0 ? val : 0);
            lsum[root] = (val >= 0 ? val : 0);
            rsum[root] = (val >= 0 ? val : 0);
            sum[root] = val;
            return;
        }
        int mid = (l + r) >> 1;
        if (pos <= mid)
            update(lson, l, mid, pos, val);
        else 
            update(rson, mid + 1, r, pos, val);
        popup(root);
    }
 
    LL query(int root){
        return ans[root];
    }
}seg;
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    vector<vector<int>> G(n);
    vector<array<int, 4>> edge;
    for(int i = 1; i < n; ++ i){    
        int u, v, w, b;
        cin >> u >> v >> w >> b;
        -- u, -- v;
        G[u].push_back(edge.size());
        G[v].push_back(edge.size());
        edge.push_back({u, v, w, b});
    }
    vector<LL> maxd(n, 0);
    LL ans = 0;
    function<void(int, int)> dfs = [&](int u, int fa){
        for(auto &i : G[u]){
            int v = edge[i][0] ^ edge[i][1] ^ u;
            if (v == fa)
                continue;
            int d = edge[i][3] - edge[i][2];
            dfs(v, u);
            ans = max(ans, maxd[u] + maxd[v] + d);
            maxd[u] = max(maxd[u], maxd[v] + d);
        }
    };
    dfs(1, 1);
    cout << ans << '\n';
    if (m < 100000){
        for(int i = 1; i <= m; ++ i){
            int x, y;
            cin >> x >> y;
            -- x;
            edge[x][2] = y;
            ans = 0;
            fill(maxd.begin(), maxd.end(), 0);
            dfs(1, 1);
            cout << ans << '\n';
        }
    }else{
        int ok1 = true;
        for(int i = 0; i < n - 1; ++ i){
            ok1 &= (edge[i][0] == i && edge[i][1] == i + 1);
        }
        if (ok1){
            // A
            vector<int> a(n);
            for(int i = 1; i < n; ++ i){
                a[i] = edge[i - 1][3] - edge[i - 1][2];
            }
            seg.build(1, 1, n - 1, a);
            for(int i = 1; i <= m; ++ i){
                int x, y;
                cin >> x >> y;
                -- x;
                edge[x][2] = y;
                seg.update(1, 1, n - 1, x + 1, edge[x][3] - edge[x][2]);
                cout << seg.query(1) << '\n';
            }
        }else{
            // C
            vector<set<array<LL, 2>>> anss(n), maxs(n);
            vector<unordered_map<int, LL>> anss_id(n), maxs_id(n);
            vector<int> deep(n), f(n);
            function<void(int, int)> dfs2 = [&](int u, int fa){
                f[u] = fa;
                int leave = true;
                for(auto &i : G[u]){
                    int v = edge[i][0] ^ edge[i][1] ^ u;
                    if (v == fa)
                        continue; 
                    leave = false;
                    deep[v] = deep[u] + 1;
                    dfs2(v, u); 
                    int d = edge[i][3] - edge[i][2];
 
                    LL ans_val = (*anss[v].rbegin())[0];
                    anss[u].insert({ans_val, v});
                    anss_id[u][v] = ans_val;
 
 
                    LL maxs_val = (*maxs[v].rbegin())[0] + d;
                    maxs[u].insert({maxs_val, v});
                    maxs_id[u][v] = maxs_val;
                }             
                anss[u].insert({0, -1});
                maxs[u].insert({0, -1});
 
                if (maxs[u].size() > 1){
                    auto c1 = maxs[u].rbegin();
                    auto c2 = next(c1);
                    anss[u].insert({(*c1)[0] + (*c2)[0], -2});
                    anss_id[u][-2] = (*c1)[0] + (*c2)[0];
                }
            };
            dfs2(0, -1);
            for(int i = 0; i < m; ++ i){
                int x, y;
                cin >> x >> y;
                -- x;
                edge[x][2] = y;
                int d = edge[x][3] - edge[x][2];
                ans = 0;
                int cur = (deep[edge[x][0]] < deep[edge[x][1]] ? edge[x][0] : edge[x][1]);
                int son = cur ^ edge[x][0] ^ edge[x][1];
                while(cur != -1){
                    maxs[cur].erase({maxs_id[cur][son], son});
                    maxs_id[cur][son] = (*maxs[son].rbegin())[0] + d;
                    maxs[cur].insert({maxs_id[cur][son], son});
 
                    anss[cur].erase({anss_id[cur][son], son});
                    anss_id[cur][son] = (*anss[son].rbegin())[0];
                    anss[cur].insert({anss_id[cur][son], son});
 
                    anss[cur].erase({anss_id[cur][-2], -2});
                    if (maxs[cur].size() > 1){
                        auto c1 = maxs[cur].rbegin();
                        auto c2 = next(c1);
                        anss_id[cur][-2] = (*c1)[0] + (*c2)[0];
                        anss[cur].insert({anss_id[cur][-2], -2});
                    }
 
                    son = cur;
                    cur = f[cur];
                }
                ans = max(0ll, (*anss[0].rbegin())[0]);
                
                cout << ans << '\n';
            }
 
        }
    }
    return 0;
}

运行结果:

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

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

相关文章

PyTorch自动梯度计算(注意点)

if params.grad is not None: params.grad.zero_() 我们实际的运算往往会涉及到若干个requires-grad为true的张量进行运算&#xff0c;在这种情况下&#xff0c;Pytorch会计算整个计算图上的损失的导数&#xff0c;并把这些结果累加到grad属性中。多次调用backward()会导致梯度…

chrome升级后,调试vue在控制台输出总是显示cjs.js

当前chrome版本120.0.6099.72 在vue中使用console.log输出时&#xff0c;总是显示cjs.js多少多少行&#xff0c;不能显示源文件名及行数 【解决方案】 打开控制台的设置 左侧找到“Ignore List”&#xff0c;取消勾选"enable Lgnore Listing"&#xff0c;并重启chr…

基于C/C++的非系统库自定义读写ini配置

INI文件由节、键、值组成。 节 [section] 参数 &#xff08;键值&#xff09; namevalue 这里将常用的操作方式封装成了一个dll供外部使用 // 下列 ifdef 块是创建使从 DLL 导出更简单的 // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 LIBCFG_EXPORTS // 符号…

紫光FPGA DDR3 IP使用和注意事项(axi4协议)

紫光DDR3 IP使用 对于紫光ddr3 IP核的使用需要注意事情。 阅读ddr ip手册&#xff1a; 1、注意&#xff1a;对于写地址通道&#xff0c;axi_awvalid要一直拉高&#xff0c;axi_awready才会拉高。使用的芯片型号时PG2L100H-6FBG676&#xff0c;不同的型号IP核接口和axi的握手协…

wireshark下载安装

下载 Wireshark Download 等待下载完成 安装 双击 下面的一定垚勾选上 下图的也一定要勾选上 修改为不重启&#xff0c;不需要重启也是正常的

嵌入式中的门电路详讲

NOT门电路 NOT(非门)是数字逻辑电路中的一种基本逻辑门,也称为反相器。它执行的是逻辑非操作,即将输入信号取反。NOT门具有一个输入和一个输出。 A输入,B输出,以下是真值表: A B 0 1 1 0 AND门电路 AND(与门)是数字逻辑电路中的一种基本逻辑门,用于执行逻辑与操作。…

从 0 开始实现一个 SpringBoot + Vue 项目

从 0 开始实现一个 SpringBoot Vue 项目 从 0 开始实现一个 SpringBoot Vue 项目软件和工具创建 SpringBoot 后端项目创建 MySQL 数据库配置文件实现增删改查接口Model 层mapper 层service 层controller 层测试 从 0 开始实现一个 SpringBoot Vue 项目 软件和工具 后端开发…

jmeter如何循环运行到csv文件最后一行后停止

1、首先在线程组中设置’循环次数‘–勾选永远 2、csv数据文件设置中设置&#xff1a; 遇到文件结束符再次循环?——改为&#xff1a;False 遇到文件结束符停止线程?——改为&#xff1a;True 3、再次运行就会根据文档的行数运行数据 &#xff08;如果需要在循环控制器中&…

[python]用python获取EXCEL文件内容并保存到DBC

目录 关键词平台说明背景所需库实现过程方法1.1.安装相关库2.代码实现 关键词 python、excel、DBC、openpyxl 平台说明 项目Valuepython版本3.6 背景 在搭建自动化测试平台的时候经常会提取DBC文件中的信息并保存为excel或者其他文件格式&#xff0c;用于自动化测试。本文…

STL容器之string(上)

目录 什么是STL string类 string类常见接口 string类的常见构造函数 string类对象的容器操作 string类对象的访问及遍历操作 string类对象的修改操作 拓展 从本期开始&#xff0c;我们将正式学习C中的STL&#xff0c;美国的麦克阿瑟将军说过&#xff1a;“C不能没有STL就…

轻量封装WebGPU渲染系统示例<52>- Json数据描述材质、纹理等3D渲染场景信息

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/DataDrivenScene3.ts 当前示例运行效果: ​​​​​​​ Json数据: {"renderer": {"mtplEnabled": true,"camera": {"eye&quo…

Linux实操——安装Mysql

安装Mysql 一、检查是否已经安装了mariadb数据库,并卸载二、下载mysql包&#xff0c;并通过ftp上传到服务器三、解压安装包四、创建数据存储文件夹五、创建执行mysqld命令的用户&#xff0c;并初始化mysql六、启用传输安全七、启动mysql&#xff0c;验证是否安装成功 总结 博主…

若依 ruoyi-vue3+ts-plus+ 宇道 yudao-ruoyi-vue-pro前端显示部门名称

想在 index.vue 上显示列表里对应的部门名称 效果 引入dept import * as DeptApi from "/api/system/dept"; 初始化时 /** 初始化 **/ onMounted(async () > {getList();deptNameList.value await DeptApi.getSimpleDeptList(); }) 加载id 对应的部门名称 …

威联通硬盘休眠后修改系统定时任务

按照网上一些教程&#xff0c;成功将威联通的机械硬盘设置了自动休眠。但是发现每天有多个整点硬盘会自动唤醒&#xff0c;怀疑是系统内置的定时任务触发了硬盘唤醒。 通过查看系统日志中事件和访问记录&#xff0c;判断出一些引发硬盘唤醒的自动任务&#xff0c;将这些定时任…

机器学习项目精选 第一期:超完整数据科学资料合集

大噶吼&#xff0c;不说废话&#xff0c;分享一波我最近看过并觉得非常硬核的资源&#xff0c;包括Python、机器学习、深度学习、大模型等等。 1、超完整数据科学资料合集 地址&#xff1a;https://github.com/krishnaik06/The-Grand-Complete-Data-Science-Materials Pytho…

【基础算法】试除法判定质数(优化)

文章目录 算法优化模板题目代码实现 算法优化模板 bool is_prime(int n){if(n < 2) return false;for(int i 2;i < n / i;i ){ //优化内容if(n % i 0){return false;}}return true; }注意这里的一个总要优化是for循环的终止条件是i<n/i。为什么不是i<n或者i<…

Java EE 网络之网络初识

文章目录 1. 网络发展史1.1 独立模式1.2 网络互连1.3 局域网 LAN1.4 广域网 WAN 2. 网络通信基础2.1 IP 地址2.2 端口号2.3 认识协议2.4 五元组2.5 协议分层2.5.1 什么是协议分层2.5.2 分层的作用2.5.3 OSI七层协议2.5.4 TCP/IP五层协议2.5.5 网络设备所在分层 2.6 分装和分用 …

10天玩转Python第9天:python 面向对象 全面详解与代码示例

今日内容 异常 模块和包 导入模块(导包)if __name__ "__main__": Unitest 框架的学习 了解, 基本组成 异常 异常传递[了解] 异常传递是 Python 中已经实现好了,我们不需要操作, 我们知道异常会进行传递. ​ 异常传递: 在函数嵌套调用的过程中, 被调用的函数 ,发…

获取MODIS的NDVI/EVI产品

目录 简介源代码运行流程参考博文 简介 本项目是使用MODIS的NDVI产品&#xff08;MOD13Q1&#xff09;,可获取从2000年至今的所有数据&#xff0c;更新频率为16天 MOD13Q1 V6.1产品以每像素为基础提供植被指数(VI)值。这里有两个主要的植被层。第一种是归一化植被指数(NDVI)&a…

LeedCode刷题---滑动窗口问题(二)

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、将X减到0的最小操作数 题目链接&#xff1a;将 x 减到 0 的最小操作数 题目描述 给你一个整数数组 nums 和一个整数 x 。每一…