博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LOJ#6032. 「雅礼集训 2017 Day2」水箱
阅读量:7248 次
发布时间:2019-06-29

本文共 3114 字,大约阅读时间需要 10 分钟。

首先可以有一个平方复杂度的 \(DP\)

\(f_{i,j}\) 表示前面 \(i\) 个小格,高度为 \(j\) 的最大答案
\(h_i\) 表示隔板 \(i\) 的高度
\(j\le h_i\) 时,转移到 \(f_{i+1,k},k\in [0,h_i]\)
否则 \(f{i,j}\rightarrow f_{i+1,j}\)
\(m\) 个限制直接区间加法就好了
只需要做到区间对一个数取 \(max\),区间加法,区间询问 \(max\) 即可
直接令标记 \((a,b)\) 表示加 \(a\) 后对 \(b\)\(max\),用在线段树上就好了

# include 
using namespace std;typedef long long ll;const int maxn(3e5 + 5);int n, m, test, o[maxn], len, h[maxn], ans, mx[maxn << 2];vector
v1[maxn], v0[maxn];struct Lazy_Tag { int ad, mx; inline Lazy_Tag operator +(Lazy_Tag b) const { return (Lazy_Tag){ad + b.ad, max(mx + b.ad, b.mx)}; } inline int Calc(int x) { return max(x + ad, mx); }} tag[maxn << 2];inline void Puttag(int x, Lazy_Tag v) { tag[x] = tag[x] + v, mx[x] = v.Calc(mx[x]);}inline void Pushdown(int x) { if (!tag[x].ad && !tag[x].mx) return; Puttag(x << 1, tag[x]), Puttag(x << 1 | 1, tag[x]); tag[x].ad = tag[x].mx = 0;}void Modify(int x, int l, int r, int ql, int qr, Lazy_Tag v) { if (ql <= l && qr >= r) Puttag(x, v); else { int mid = (l + r) >> 1; Pushdown(x); if (ql <= mid) Modify(x << 1, l, mid, ql, qr, v); if (qr > mid) Modify(x << 1 | 1, mid + 1, r, ql, qr, v); mx[x] = max(mx[x << 1], mx[x << 1 | 1]); }}int Query(int x, int l, int r, int ql, int qr) { if (ql <= l && qr >= r) return mx[x]; else { int mid = (l + r) >> 1, ret = 0; Pushdown(x); if (ql <= mid) ret = Query(x << 1, l, mid, ql, qr); if (qr > mid) ret = max(ret, Query(x << 1 | 1, mid + 1, r, ql, qr)); mx[x] = max(mx[x << 1], mx[x << 1 | 1]); return ret; }}int main() { int i, j, p, l1, l2, y, k; scanf("%d", &test); while (test--) { memset(mx, 0, sizeof(mx)), memset(tag, 0, sizeof(tag)); scanf("%d%d", &n, &m), o[len = 1] = 1e9; for (i = 1; i < n; ++i) scanf("%d", &h[i]), o[++len] = h[i]; for (i = 1; i <= n; ++i) v1[i].clear(), v0[i].clear(); for (i = 1; i <= m; ++i) { scanf("%d%d%d", &p, &y, &k), ++y; k ? v1[p].push_back(y) : v0[p].push_back(y); o[++len] = y, o[++len] = y - 1; } sort(o + 1, o + len + 1), len = unique(o + 1, o + len + 1) - o - 1; for (i = 1; i < n; ++i) h[i] = lower_bound(o + 1, o + len + 1, h[i]) - o; for (i = 1; i <= n; ++i) sort(v1[i].begin(), v1[i].end()), sort(v0[i].begin(), v0[i].end()); for (i = 1; i <= n; ++i) { l1 = v1[i].size(), l2 = v0[i].size(); for (j = 0; j < l1; ++j) { y = lower_bound(o + 1, o + len + 1, v1[i][j]) - o; Modify(1, 1, len, y, len, (Lazy_Tag){1, 0}); } for (j = 0; j < l2; ++j) { y = lower_bound(o + 1, o + len + 1, v0[i][j]) - o; if (y > 1) Modify(1, 1, len, 1, y - 1, (Lazy_Tag){1, 0}); } if (i == n) break; y = Query(1, 1, len, 1, h[i]); Modify(1, 1, len, 1, h[i], (Lazy_Tag){0, y}); } printf("%d\n", mx[1]); } return 0;}

转载于:https://www.cnblogs.com/cjoieryl/p/10317096.html

你可能感兴趣的文章
codeforces1141D题解(暴力+贪心)
查看>>
Java Spring Boot 2.0实战MyBatis连接池阿里Druid与SQL性能监控
查看>>
信用算力基于 RocketMQ 实现金融级数据服务的实践
查看>>
基于oauth 2.0 实现第三方开放平台
查看>>
kubernetes1.4 基础篇:Learn Kubernetes 1.4 by 6 steps(1):概要
查看>>
百万下载量的 Android 应用后台收集用户信息
查看>>
SQL Server 多表数据增量获取和发布 1
查看>>
C3P0连接池
查看>>
这 25 个开源机器学习项目,一般人我不告诉 Ta
查看>>
【WePY小程序框架实战四】-使用async&await异步请求数据
查看>>
iOS UIImageView(图片)
查看>>
可折叠显示的发光搜索表单
查看>>
PostgreSQL 10.1 手册_部分 II. SQL 语言_第 12 章 全文搜索_12.2. 表和索引
查看>>
java使用正则表达式判断手机号,固定电话,身份证,邮箱,url,车牌号,日期,ip地址,mac,人名等...
查看>>
新手也能轻松掌握的分布式系统「事务」技巧
查看>>
iOS开发之使用Git的基本使用(一)
查看>>
配置云存储网关在线服务支持多个互联VPC-高速通道版
查看>>
6个步骤从头开始编写机器学习算法:感知器案例研究
查看>>
NCalc 学习笔记 (三)
查看>>
NetBeans 成为 Apache 软件基金会顶级项目
查看>>