传送门

首先可以有一个平方复杂度的 \(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 <bits/stdc++.h>
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 <int> 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;
}

LOJ#6032. 「雅礼集训 2017 Day2」水箱的更多相关文章

  1. loj#6032. 「雅礼集训 2017 Day2」水箱(并查集 贪心 扫描线)

    题意 链接 Sol 神仙题+神仙做法%%%%%%%% 我再来复述一遍.. 首先按照\(y\)坐标排序,然后维护一个扫描线从低处往高处考虑. 一个连通块的内状态使用两个变量即可维护\(ans\)表示联通 ...

  2. loj #6032. 「雅礼集训 2017 Day2」水箱 线段树优化DP转移

    $ \color{#0066ff}{ 题目描述 }$ 给出一个长度为 \(n\) 宽度为 \(1\) ,高度无限的水箱,有 \(n-1\) 个挡板将其分为 \(n\) 个 \(1 - 1\) 的小格, ...

  3. loj#6033. 「雅礼集训 2017 Day2」棋盘游戏(二分图博弈)

    题意 链接 Sol 第一次做在二分图上博弈的题..感觉思路真是清奇.. 首先将图黑白染色. 对于某个点,若它一定在最大匹配上,那么Bob必胜.因为Bob可以一直沿着匹配边都,Alice只能走非匹配边. ...

  4. [LOJ#6033]. 「雅礼集训 2017 Day2」棋盘游戏[二分图博弈、匈牙利算法]

    题意 题目链接 分析 二分图博弈经典模型,首先将棋盘二分图染色. 考虑在某个最大匹配中: 如果存在完美匹配则先手必败,因为先手选定的任何一个起点都在完美匹配中,而后手则只需要走这个点的匹配点,然后先手 ...

  5. loj#6034 「雅礼集训 2017 Day2」线段游戏

    分析 区间李超树板子题 代码 #include<bits/stdc++.h> using namespace std; #define db double const int inf = ...

  6. 「雅礼集训 2017 Day2」水箱

    题目链接 题意分析 我们用\(f[i][j]\)表示当前到达第\(i\)个位置水位高度为\(j\)的答案 如果那么\(h[i]\)为\(i\)和\(i+1\)之间的支柱高度 那么如果\(j≤h[i]\ ...

  7. 「雅礼集训 2017 Day2」水箱 (数据结构+dp ,一个log)

    题面 题解 在网上看到有些做法,有什么平衡树.启发式合并等等总之复杂度O(Tnlog^2(n))的不优做法,这里我就用一个O(Tnlogn)的做法好了 其实大体上推导的思路都是一样的. 我们很容易发现 ...

  8. 「雅礼集训 2017 Day2」解题报告

    「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...

  9. [LOJ 6031]「雅礼集训 2017 Day1」字符串

    [LOJ 6031] 「雅礼集训 2017 Day1」字符串 题意 给定一个长度为 \(n\) 的字符串 \(s\), \(m\) 对 \((l_i,r_i)\), 回答 \(q\) 个询问. 每个询 ...

随机推荐

  1. Storm的并行度

    在Storm集群中,运行Topolopy的实体有三个:工作进程,executor(线程),task(任务),下图可以形象的说明他们之间的关系. 工作进程 Storm集群中的一台机器会为一个或则多个To ...

  2. 【Hight Performance Javascript】——脚本加载和运行

    脚本加载和运行 当浏览器遇到一个<script>标签时,无法预知javascript是否在<p>标签中添加内容.因此,浏览器停下来,运行javascript代码,然后继续解析. ...

  3. day 52 Django 的中间件加载顺序

    前情提要: django的中间键的作用是进行加载 可以通过中间键进行辅助操作 1.中间件的概念 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局 ...

  4. Vim实用技巧系列 - 代码注释

    在写代码时候,有时候需要临时注释掉一部分代码,之后还要取消这些注释.真麻烦.那么,用Vim怎么做这件事呢? 第一种方法,块模式.                 再次声明,本系列全部以windows下 ...

  5. Inno Setup入门(二十三)——Inno Setup类参考(9)

    今天就简单说一下ProgressBar. TNewProgressBar = class(TWinControl)   property Min: Longint; read write;   pro ...

  6. MySQL 5.7.14 win10安装

    1. 下载: http://dev.mysql.com/downloads/mysql/

  7. Spring Security构建Rest服务-1000-使用SpringSocial开发第三方登录之大白话OAuth协议

    OAuth协议简介 OAuth协议要解决的问题    OAuth协议中的各种角色 OAuth协议运行流程 OAuth协议,在网上也看了一些资料,意思就是给你颁发一个临时的通行证,你拿着这个通行证可以访 ...

  8. Vue路由router-link的使用

    Vue路由router-link的使用 相关Html: <!DOCTYPE html> <html lang="en"> <head> < ...

  9. 图解安卓-c++开发-通过java 调用c++ jni的使用

    接着上一节 ,很多事情用java做,效率要差一点(尤其是游戏),所以要用c++来实现,那么java如何调用c++ 首先建议一个工程 HelloJni如下图: 按照默认的配置下一步,直到完成 . 如下图 ...

  10. Self-Attention与Transformer

    直观理解与模型整体结构 先来看一个翻译的例子“I arrived at the bank after crossing the river” 这里面的bank指的是银行还是河岸呢,这就需要我们联系上下 ...