「CF484E」Sign on Fence「整体二分」「线段树」
题意
给定一个长度为\(n\)的正整数序列,第\(i\)个数为\(h_i\),\(m\)个询问,每次询问\((l, r, w)\),为\([l, r]\)所有长度为\(w\)的子区间最小值的最大值。(类似于一类特殊的直方图最大子矩形问题)
\(1 \leq n, m \leq 10^5\)
题解
我们考虑二分答案,这样\(n\)个数变成\(01\),若\(h_i\geq mid\)则为\(0\),否则为\(1\)
每次就相当于查询存不存在长度为\(w\)的连续\(1\)。用线段树维护。
这有个问题,\([l, r]\)分成\([l, mid - 1]\)和\([mid, r]\)的时候,左区间统计不到右区间的贡献。那我们就递归左区间之前不清空线段树,等到递归右区间的时候再清空。
时间复杂度两个log
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 2e5 + 10;
struct opt { int l, r, k, id; } q[N], qL[N], qR[N];
int n, m, h[N], ans[N];
struct node { int res, l, r, len; } t[N << 2];
node operator + (const node &a, const node &b) {
node ans; ans.len = a.len + b.len;
ans.l = a.l == a.len ? a.l + b.l : a.l;
ans.r = b.r == b.len ? b.r + a.r : b.r;
ans.res = max(max(a.res, b.res), a.r + b.l);
return ans;
}
void build(int u, int l, int r) {
if(l == r) { t[u] = (node) {0, 0, 0, 1}; return ; }
int mid = (l + r) >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
t[u] = t[u << 1] + t[u << 1 | 1];
}
void ins(int u, int l, int r, int x, int y) {
if(l == r) { t[u] = (node) {y, y, y, 1}; return ; }
int mid = (l + r) >> 1;
if(x <= mid) ins(u << 1, l, mid, x, y);
else ins(u << 1 | 1, mid + 1, r, x, y);
t[u] = t[u << 1] + t[u << 1 | 1];
}
node qry(int u, int l, int r, int ql, int qr) {
if(l == ql && r == qr) return t[u];
int mid = (l + r) >> 1;
if(qr <= mid) return qry(u << 1, l, mid, ql, qr);
if(ql > mid) return qry(u << 1 | 1, mid + 1, r, ql, qr);
return qry(u << 1, l, mid, ql, mid) + qry(u << 1 | 1, mid + 1, r, mid + 1, qr);
}
void solve(int ql, int qr, int l, int r) {
if(ql > qr || l > r) return ;
if(l == r) {
for(int i = ql; i <= qr; i ++) ans[q[i].id] = l;
return ;
}
// printf("[%d, %d] & [%d, %d]\n", ql, qr, l, r);
int mid = (l + r + 1) >> 1, nl = 0, nr = 0;
for(int i = ql; i <= qr; i ++) {
if(!q[i].id) {
if(q[i].k >= mid) ins(1, 1, n, q[i].l, 1), qR[nr ++] = q[i];
else qL[nl ++] = q[i];
} else {
int res = qry(1, 1, n, q[i].l, q[i].r).res;
if(res >= q[i].k) qR[nr ++] = q[i];
else qL[nl ++] = q[i];
}
}
for(int i = 0; i < nl; i ++) q[ql + i] = qL[i];
for(int i = 0; i < nr; i ++) q[ql + nl + i] = qR[i];
solve(ql, ql + nl - 1, l, mid - 1);
for(int i = ql + nl; i <= qr; i ++) if(!q[i].id && q[i].k >= mid) ins(1, 1, n, q[i].l, 0);
solve(ql + nl, qr, mid, r);
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i ++) scanf("%d", h + i), q[i] = (opt) {i, 0, h[i], 0};
int l = *min_element(h + 1, h + n + 1);
int r = *max_element(h + 1, h + n + 1);
scanf("%d", &m);
for(int i = n + 1; i <= n + m; i ++) {
scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].k); q[i].id = i - n;
}
build(1, 1, n); solve(1, n + m, l, r);
for(int i = 1; i <= m; i ++) printf("%d\n", ans[i]);
return 0;
}
「CF484E」Sign on Fence「整体二分」「线段树」的更多相关文章
- (困难) CF 484E Sign on Fence,整体二分+线段树
Bizon the Champion has recently finished painting his wood fence. The fence consists of a sequence o ...
- 【XSY2720】区间第k小 整体二分 可持久化线段树
题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...
- 2019.01.14 bzoj5343: [Ctsc2018]混合果汁(整体二分+权值线段树)
传送门 整体二分好题. 题意简述:nnn种果汁,每种有三个属性:美味度,单位体积价格,购买体积上限. 现在有mmm个询问,每次问能否混合出总体积大于某个值,总价格小于某个值的果汁,如果能,求所有方案中 ...
- P5163 WD与地图(整体二分+权值线段树)
传送门 细节要人命.jpg 这题思路太新奇了--首先不难发现可以倒着做变成加边,但是它还需要我们资瓷加边的同时维护强连通分量.显然加边之后暴力跑是不行的 然后有一个想法,对于一条边\((u,v)\), ...
- 【CF484E】Sign on Fence(主席树)
[CF484E]Sign on Fence(主席树) 题面 懒得贴CF了,你们自己都找得到 洛谷 题解 这不就是[TJOI&HEOI 排序]那题的套路吗... 二分一个答案,把大于答案的都变成 ...
- 「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数
「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数 题面描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数, ...
- 洛谷P1527 [国家集训队] 矩阵乘法 [整体二分,二维树状数组]
题目传送门 矩阵乘法 题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入输出格式 输入格式: 第一行两个数N,Q,表示矩阵大小和询问组数: 接下来N行N列一共N* ...
- [bzoj4009] [HNOI2015]接水果 整体二分+扫描线+dfs序+树状数组
Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果. 由于她已经DT FC 了The big black, 她觉得这个游戏太简单了,于是发明了一个更 加 ...
- 「CF319E」Ping-Pong「线段树」「并查集」
题意 规定区间\((a,b)\)到区间\((c,d)\)有边当且仅当\(c<a<d\)或\(c<b<d\). 起初区间集合为空.有\(n\)(\(n\leq 10^5\))次操 ...
随机推荐
- MySql数据库 优化
MySQL数据库优化方案 Mysql的优化,大体可以分为三部分:索引的优化,sql慢查询的优化,表的优化. 开启慢查询日志,可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,才能更 ...
- (五)Activiti之获取流程定义图片和流程定义删除
一.获取流程定义图片 /** * 通过流程部署ID获取流程图图片 */ @Test public void getImageById()throws Exception{ InputStream in ...
- Asp.Net Core 存储Cookie 的问题
Asp.Net Core 2.1生成的项目模板默认实现了<欧洲常规数据保护法规 (GDPR)>支持.这就使得我们的程序要想成功的存储除了用户身份以外的cookie通常是需要用户同意的. 3 ...
- HALC:用于长读取错误纠正的高吞吐量算法
背景: 第三代PacBio SMRT长读取可以有效地解决第二代测序技术的读长问题,但包含大约15%的测序错误.已经设计了几种纠错算法以有效地将错误率降低到1%,但是它们丢弃了大量未校正的碱基,因此导致 ...
- 表格中的DOM
通过DOM来操作table跟在html中操作table是不一样的,下面来看看怎样通过DOM来操作table. 按照table的分布来创建: <table> <thead> &l ...
- mycat 报错 java.lang.OutOfMemoryError: Java heap space
今天排查mysql的错误日志发现 wrapper.log 中有如下错误日志 INFO | jvm 1 | 2019/10/20 12:52:31 | java.lang.OutOfMem ...
- 一款结合nmap及mascan还有shodan的扫描脚本
github在这里 https://github.com/s0md3v/Silver 很是舒服 Usage Note: Silver scans all TCP ports by default i. ...
- sql查询并把数据更新到另一个表中
update OpenBills set peopleCount=(select rtNumber from Rooms where obId='ZD201005223') where obId='Z ...
- BufferInputStream、BufferOutputStream、BufferedReader、BufferedWriter、Java代码使用BufferedReader和BufferedWriter实现文本文件的拷贝
BufferInputStream和BufferOutputStream的特点: 缓冲字节输入输出流,缓冲流是处理流,它不直接连接数据源/目的地,而是以一个字节流为参数,在节点流的基础上提供一些简单操 ...
- JS 详解 Cookie、 LocalStorage 与 SessionStorage-转载
记录一下这些知识,有时候用到会忘记,对原文作者表达感谢. 附上原文链接:JS 详解 Cookie. LocalStorage 与 SessionStorage 基本概念 Cookie Cookie 是 ...