题解 [NOISG2025 Prelim] Lasers 2

news/2025/2/25 22:26:50/文章来源:https://www.cnblogs.com/caijianhong/p/18737441

solution

因为我们可以将所有激活墙全部放在最长的激活墙后面,而如果最长的激活墙比最长未激活墙短(也就是全场最长墙未激活),那么答案就是未激活墙的并的大小,否则我们需要找一个地方放置这个激活的全场最长墙,然后答案是未激活墙的并再并上这个最长墙的大小。

一堆区间的并还是太困难了,我们不妨按照并的连续段进行 dp。我们把问题改成最大化选中的区间的价格的和(也就是我们着眼于的是未激活的墙),先处理一个 \(sum[l,r]\) 表示所有 \(\subseteq[l, r]\) 的区间的价格,然后直接 dp,设\(f_i\) 表示考虑完 \([1, i]\) 的选择情况的最大价格,转移就 \(O(n)\) 转移。这只是一个雏形,我们还需要的是:

  1. 需要有一个连续段的长度大于全场最长墙,然后再看看能不能计入全场最长墙的价格。使用一个 0/1 记录即可。
  2. 需要记答案,记录有多少个空位(记作变量 \(w\))。使用 \(O(n)\) 的时空代价即可。

此时复杂度 \(O(n^3)\),需要优化。

发现我们将前面的 \(O(n^2)\) 个状态排成矩阵的形式,那么就是形如矩阵的某条对角线对位加上 \(sum\) 的某一列的最大值贡献到 \(f_{i, w}\),且随着 \(i\) 增加这些对角线不会变,只有 \(sum\) 的那一列会增加。然而这样的话可以不在一开始处理 \(sum\),而是 \(i\) 增加的时候将右端点为 \(i\) 的区间拿出来将每条对角线的某个前缀进行整体加。所以我们对每一条对角线用线段树维护即可,需要支持区间加和区间最大值(因为有一个“连续段的长度大于全场最长墙”的特殊转移需要区间最大值)。复杂度做到 \(O(n^2\log n)\) 也就是 \(O(hw\log w)\)

code

#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#define debug(...) fprintf(stderr, ##__VA_ARGS__)
#else
#define debug(...) void(0)
#define endl "\n"
#endif
using LL = long long;
template <class T> T& chkmin(T& x, const T& y) { return x = min(x, y); }
template <class T> T& chkmax(T& x, const T& y) { return x = max(x, y); }
constexpr int N = 2010;
struct wall {int l, r, c;int length() const { return r - l + 1; }friend bool operator<(const wall& lhs, const wall& rhs) { return lhs.length() < rhs.length(); }
};
struct segtree {LL ans[N << 2], tag[N << 2];segtree() {memset(ans, ~0x3f, sizeof ans);memset(tag, 0, sizeof tag);}void spread(int p, LL k) { tag[p] += k, ans[p] += k; }void maintain(int p) { ans[p] = max(ans[p << 1], ans[p << 1 | 1]); }void pushdown(int p) { spread(p << 1, tag[p]), spread(p << 1 | 1, tag[p]), tag[p] = 0; }void setValue(int x, LL v, int p, int l, int r) {if (l == r) return ans[p] = v, void();int mid = (l + r) >> 1;pushdown(p);if (x <= mid) setValue(x, v, p << 1, l, mid);else setValue(x, v, p << 1 | 1, mid + 1, r);maintain(p);}void modify(int ql, int qr, LL k, int p, int l, int r) {if (ql <= l && r <= qr) return spread(p, k);int mid = (l + r) >> 1;pushdown(p);if (ql <= mid) modify(ql, qr, k, p << 1, l, mid);if (mid < qr) modify(ql, qr, k, p << 1 | 1, mid + 1, r);maintain(p);}LL query(int ql, int qr, int p, int l, int r) {if (ql <= l && r <= qr) return ans[p];int mid = (l + r) >> 1;pushdown(p);LL ret = -1e18;if (ql <= mid) chkmax(ret, query(ql, qr, p << 1, l, mid));if (mid < qr) chkmax(ret, query(ql, qr, p << 1 | 1, mid + 1, r));return ret;}
} tr[N][2];
int n, m;
LL lim, f[N][2][N];
vector<wall> rgs[N];
int main() {
#ifndef NFcin.tie(nullptr)->sync_with_stdio(false);
#endifcin >> m >> n >> lim, lim = -lim;wall maxw = {0, -1, 0};for (int i = 1, l, r, c; i <= m; i++) cin >> l >> r >> c, lim += c, rgs[r].push_back({l, r, c}), maxw = max(maxw, wall{l, r, c});rgs[maxw.r].push_back({maxw.l, maxw.r, -maxw.c});memset(f, ~0x3f, sizeof f);f[0][0][0] = 0;for (int i = 1; i <= n; i++) {f[i][0][0] = 0;for (int t : {0, 1}) {for (int w = 1; w <= i; w++) {auto& seg = tr[w - i + n][t];seg.setValue(i, f[i - 1][t][w - 1], 1, 1, n);for (auto wl : rgs[i]) seg.modify(1, wl.l, wl.c, 1, 1, n);chkmax(f[i][t][w], max(seg.ans[1], f[i - 1][t][w]));if (t == 0 && i >= maxw.length()) {if (maxw.r <= i) seg.modify(1, maxw.l, maxw.c, 1, 1, n);chkmax(f[i][1][w], seg.query(1, i - maxw.length() + 1, 1, 1, n));if (maxw.r <= i) seg.modify(1, maxw.l, -maxw.c, 1, 1, n);}}}}for (int i = 1; i <= n; i++) {for (int t : {0, 1}) {for (int w = 0; w <= n; w++) if (f[i][t][w] >= 0) debug("f[%d][%d][%d] = %lld\n", i, t, w, f[i][t][w]);}}for (int w = 0; w <= n; w++) if (f[n][1][w] >= lim) return cout << n - w << endl, 0;assert(false);return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NetPad:一个.NET开源、跨平台的C#编辑器

前言 今天大姚给大家分享一个基于.NET开源、跨平台的C#编辑器和游乐场:NetPad。 项目介绍 NetPad是一个基于.NET开源(MIT License)、跨平台的C#编辑器和游乐场,它允许用户立即运行C#代码,无需创建和管理项目。项目技术栈.NET:作为底层框架,提供强大的开发能力和跨平台支…

upload-labs/Pass-18条件竞争绕过

根据代码可以看出,Pass-18 先保存了文件然后再判断文件是否合法,不合法就删除文件; 其他文件上传漏洞都是先判断文件是否合法然后再保存文件 因此可以知道,我们上传的不合法的文件是可以传到服务器的,在上传到服务器和文件删除之间会有一个间隙 我们可以利用这个间隙来绕过…

14 Java的Stream流详解

Stream是[Java 8](https://so.csdn.net/so/search?q=Java 8&spm=1001.2101.3001.7020) API添加的一个新的抽象,称为流Stream,以一种声明性方式处理数据集合(侧重对于源数据计算能力的封装,并且支持序列与并行两种操作方式)Stream流是从支持数据处理操作的源生成的元素…

作业1:自我介绍+软工五问

项目 内容这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/SoftwareEngineeringClassof2023这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/SoftwareEngineeringClassof2023/homework/13325这个作业的目标 熟练掌握github、git、markdown和博客园的使用1.…

基于电压电流双闭环控制的三相整流器系统simulink建模与仿真

1.课题概述 基于电压电流双闭环控制的三相整流器系统simulink建模与仿真。2.系统仿真结果 (完整程序运行后无水印)3.核心程序与模型 版本:MATLAB2022a4.系统原理简介三相整流器作为电力电子变换的核心部件,广泛应用于各种工业及能源系统中,其性能直接影响到整个系统的效率…

[BUUCTF]刷题记录PWN——ez_pz_hackover_2016

静态分析比较重要的函数,一个strlen可以利用\x00来绕过,然后对输入的字符串进行检查,最后进入vulnmemcoy: C 库函数 void *memcpy(void *str1, const void *str2, size_t n) 从存储区 str2 复制 n 个字节到存储区 str1。也就是说,vuln里的memcpy函数会把,我们输入的内容取…

基于信息论的高动态范围图像评价算法matlab仿真

1.程序功能描述 基于信息论的高动态范围图像评价算法matlab仿真,利用一种自然图像的概率模型对图像的熵与成像动态范围之间的关系进行了数值模拟,得到了具有普遍意义上的理想成像动态范围的计算公式,公式指出了对自然景物完善成像所需的最大动态范围;给出了图像熵与动态…

BloomFilter详解

目录BloomFilter 原理:问题引入:黑名单管理程序哈希、哈希函数BloomFilter :3.4 BloomFilter 的缺陷、改进:代码实现黑名单blacklist.py:普通的实现方法set.py:哈希函数hash.py:4.4 BloomFilter 实现方法bloomfilter.py: BloomFilter 原理: ​ 我们将从哈希函数开始…

【ABP】项目示例(4)——领域服务

领域服务 在上一章节中,已经完成了仓储的设计,在这一章节中,实现领域服务,即业务的核心逻辑 领域服务主要处理特定领域的业务逻辑,对内协调和整合聚合根与各个实体的业务关系,对外作为业务的边界,供应用服务组合来提供完整复杂的功能 规约 在名称为General.Backend.Doma…

YOLOv10 解析与地平线 征程 6模型量化

一,YOLOv10 解析 1.简介 近些年来,研究人员对 YOLO 的架构设计、优化目标、数据增强策略等进行了探索,取得了显著进展。然而,后处理对非极大值抑制(NMS)的依赖阻碍了 YOLO 的端到端部署,并对推理延迟产生不利影响。此外,YOLO 中各个组件的设计缺乏全面彻底的检查,导致…

SemanticKernel之Chat

去年写过几过几篇关于SemanticKernel的文章,由于正式发布的版本与之前的版本变化较大,加上前的东京《生成式AI应用开发》活动,想把演示的Demo逐一分享出来,的以再次开启SemanticKernel系统。下面是一个Chat的例子,用户提问,如果本地有固定数据能对应,直接返回,如果没有…

7、添加特效

去除画面logo 复制一份 拖动模糊特效到复制的片段中 右键分离音频或者快捷键【ctrl+shift+s】 删除音频 添加原创特效,特效随机 有音乐的去除音乐 适当拖动放大 调整透明度 开幕特效 三秒 调整参数后,复制双份 画面特效和人物特效二选一 画面特效需要修改参数