当前位置:网站首页>P5019 [NOIP2018 提高组] 铺设道路
P5019 [NOIP2018 提高组] 铺设道路
2022-07-31 12:49:00 【WDLieqi】
[NOIP2018 提高组] 铺设道路
题目背景
NOIP2018 提高组 D1T1
题目描述
春春是一名道路工程师,负责铺设一条长度为 n n n 的道路。
铺设道路的主要工作是填平下陷的地表。整段道路可以看作是 n n n 块首尾相连的区域,一开始,第 i i i 块区域下陷的深度为 d i d_i di 。
春春每天可以选择一段连续区间 [ L , R ] [L,R] [L,R] ,填充这段区间中的每块区域,让其下陷深度减少 1 1 1。在选择区间时,需要保证,区间内的每块区域在填充前下陷深度均不为 0 0 0 。
春春希望你能帮他设计一种方案,可以在最短的时间内将整段道路的下陷深度都变为 0 0 0 。
输入格式
输入文件包含两行,第一行包含一个整数 n n n,表示道路的长度。 第二行包含 n n n 个整数,相邻两数间用一个空格隔开,第 i i i 个整数为 d i d_i di 。
输出格式
输出文件仅包含一个整数,即最少需要多少天才能完成任务。
样例 #1
样例输入 #1
6
4 3 2 5 3 5
样例输出 #1
9
提示
【样例解释】
一种可行的最佳方案是,依次选择:
[ 1 , 6 ] [1,6] [1,6]、 [ 1 , 6 ] [1,6] [1,6]、 [ 1 , 2 ] [1,2] [1,2]、 [ 1 , 1 ] [1,1] [1,1]、 [ 4 , 6 ] [4,6] [4,6]、 [ 4 , 4 ] [4,4] [4,4]、 [ 4 , 4 ] [4,4] [4,4]、 [ 6 , 6 ] [6,6] [6,6]、 [ 6 , 6 ] [6,6] [6,6]。
【数据规模与约定】
对于 30 % 30\% 30% 的数据, 1 ≤ n ≤ 10 1 ≤ n ≤ 10 1≤n≤10 ;
对于 70 % 70\% 70% 的数据, 1 ≤ n ≤ 1000 1 ≤ n ≤ 1000 1≤n≤1000 ;
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 100000 , 0 ≤ d i ≤ 10000 1 ≤ n ≤ 100000 , 0 ≤ d_i ≤ 10000 1≤n≤100000,0≤di≤10000 。
思路
这道题的正规思路是用贪心的办法来进行求解,复杂度位O(n),但这里我的解题方法是线段树,复杂度O(nlogn),正规解法在原题里面的题解可以看到。
正文来了
因为我们可以进行操作的前提条件是连续区间内不能有等于零的数,所以选的区间里面必须要全部大于零。通过观察我们很容易的发现将最小的数减为零后可以将原区间分为左右两个区间例如:
45233 4 5 2 3 3 45233 变为 23011 2 3 0 1 1 23011 然后就可变为 23 2 3 23 和 11 1 1 11
所以通过不断划分区间来让全部的数变成 0
接下来是线段树维护的信息
我们要完成上述的操作就要知道两个信息,最小值和最小值的下标,所以我们的线段树记录的就是最小值和最小值的下标。
代码
#include <bits/stdc++.h>
using namespace std;
#define IOS \ ios::sync_with_stdio(false); \ cin.tie(0); \ cout.tie(0);
#define P acos(-1);
typedef long long LL;
typedef unsigned long long ULL;
#define PII pair<int, int>
#define PDD pair<double, double>
#define Pll pair<LL, LL>
typedef unsigned long long ULL;
const double eps = 1e-7;
const int N = 1e5 + 10, M = 1e6 + 10, mod = 998244353;
const int inf = 0x3f3f3f3f;
int dx[] = {
1, -1, 0, 0, -1, 1, 1, -1}, dy[] = {
0, 0, -1, 1, -1, -1, 1, 1};
int lowbit(int x) {
return (x & -x); };
struct node
{
int l, r;
int minn, add, pos;
}tr[N * 4];
int a[N];
int n, sum;
queue<PII> q;
void pushup(int u)
{
if (tr[u << 1].minn < tr[u << 1 | 1].minn)
{
tr[u].minn = tr[u << 1].minn;
tr[u].pos = tr[u << 1].pos;
}
else
{
tr[u].minn = tr[u << 1 | 1].minn;
tr[u].pos = tr[u << 1 | 1].pos;
}
}
void pushdown(int u)
{
auto &root = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1];
if (root.add)
{
left.add += root.add, left.minn -= root.add;
right.add += root.add, right.minn -= root.add;
root.add = 0;
}
}
void build(int u, int l, int r)
{
if (l == r) tr[u] = {
l, r, a[l], 0, l};
else
{
tr[u] = {
l, r};
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}
void modify(int u, int l, int r, int d)
{
if (tr[u].l >= l && tr[u].r <= r)
{
tr[u].minn -= d;
tr[u].add += d;
return;
}
int mid = tr[u].l + tr[u].r >> 1;
pushdown(u);
if (mid >= l) modify(u << 1, l, r, d);
if (mid < r) modify(u << 1 | 1, l, r, d);
pushup(u);
}
node query(int u, int l, int r)
{
if (tr[u].l >= l && tr[u].r <= r) return tr[u];
int mid = tr[u].l + tr[u].r >> 1;
pushdown(u);
node ans1, ans2;
if (mid >= r) return query(u << 1, l, r);
else if (mid < l) return query(u << 1 | 1, l, r);
ans1 = query(u << 1, l, r), ans2 = query(u << 1 | 1, l, r);
if (ans1.minn < ans2.minn) return ans1;
return ans2;
}
void solve()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
build(1, 1, n);
q.push({
1, n});
node ans;
while (q.size())
{
int f = q.front().first, g = q.front().second;
q.pop();
ans = query(1, f, g);
sum += ans.minn;
if (ans.minn) modify(1, f, g, ans.minn);
if (ans.pos > f) q.push({
f, ans.pos - 1});
if (ans.pos < g) q.push({
ans.pos + 1, g});
}
printf("%d", sum);
}
int main()
{
int T = 1;
//scanf("%d", &T);
while (T -- )
{
solve();
}
return 0;
}
O(n) 复杂度正规解法
大坑带小坑,小坑会被大坑带着填满。
大坑会减少两者的差,相当于这部分是免费的
#include <bits/stdc++.h>
using namespace std;
#define IOS \ ios::sync_with_stdio(false); \ cin.tie(0); \ cout.tie(0);
#define P acos(-1);
typedef long long LL;
typedef unsigned long long ULL;
#define PII pair<int, int>
#define PDD pair<double, double>
#define Pll pair<LL, LL>
typedef unsigned long long ULL;
const double eps = 1e-7;
const int N = 1e5 + 10, M = 1e6 + 10, mod = 998244353;
const int inf = 0x3f3f3f3f;
int dx[] = {
1, -1, 0, 0, -1, 1, 1, -1}, dy[] = {
0, 0, -1, 1, -1, -1, 1, 1};
int lowbit(int x) {
return (x & -x); };
int n, a[N];
LL ans = 0;
void solve()
{
cin >> n;
for (int i = 1; i <= n; i ++ ) cin >> a[i];
for (int i = 2; i <= n; i ++ )
if (a[i] > a[i - 1]) ans += a[i] - a[i - 1];
cout << ans + a[1];
}
int main()
{
int T = 1;
// scanf("%d", &T);
while (T--)
{
solve();
}
return 0;
}
边栏推荐
- kernel syscore
- 使用docker搭建mysql主从
- 系统集成项目管理工程师(软考中级)知识点总结【挣值分析】【关键路径】
- 基于稳态视觉诱发电位和注意力脑电的混合脑机接口系统
- AMBA APB学习记录(AMBA 2.0)
- [core]-ARMV7-A、ARMV8-A、ARMV9-A 架构简介「建议收藏」
- 跨境电商小知识之跨境电商物流定义以及方式讲解
- Optimization of five data submission methods
- 求一份常见Oracle故障模拟场景
- Exploring Plain Vision Transformer Backbones for Object Detection Paper Reading Notes
猜你喜欢
分布式监视 Zabbix 和 Prometheus 到底怎么选?千万别用错了!
PyQt5 rapid development and actual combat 10.2 compound interest calculation && 10.3 refresh blog clicks
中望3D 2023正式发布,设计仿真制造一体化缩短产品开发周期
Architecture Camp | Module 8
centos7安装mysql5.7
ASM module in SAP Ecommerce Cloud Spartacus UI and Accelerator UI
docker部署完mysql无法连接
Introduction to using NPM
ECCV2022:在Transformer上进行递归,不增参数,计算量还少!
PyQt5 rapid development and actual combat 9.7 Automated testing of UI layer
随机推荐
dosbox基础使用[通俗易懂]
Centos7 install mysql5.7 steps (graphical version)
认知—运动康复医疗机器人应用设计
sqlalchemy determines whether a field of type array has at least one consistent data with an array
荣耀手机参数写错,客服认为没错
CentOS7 —— yum安装mysql
Fully Dynamically Constrained Robot Efficient Time-Optimal Trajectory Planning
最长算术(暑假每日一题 11)
函数的参数
中望3D 2023正式发布,设计仿真制造一体化缩短产品开发周期
Quickly learn database management
0x80070570 The file or directory is damaged and cannot be deleted (how to delete 0x80070091)
基于生物激励神经网络的室内实时激光SLAM控制方法
kernel syscore
ECCV2022:在Transformer上进行递归,不增参数,计算量还少!
ipv4和ipv6对比(IPV4)
PyQt5 rapid development and actual combat 10.2 compound interest calculation && 10.3 refresh blog clicks
深度学习基本概念
[core]-ARMV7-A, ARMV8-A, ARMV9-A Architecture Introduction "Recommended Collection"
五种数据提交方式的优化