[传送门]

题意就是给一排围栏,每个围栏都有一个高度,查询区间$\left[l, r\right]$之间长度为$w$的子区间的最小高度的最大值。
首先,这个最大值肯定是这个区间里的围栏的某个高度,如果是一个未出现过的高度,显然能有更高的高度满足条件。
那么就可以考虑在离散化后的高度数组里二分答案,然后check一下这个区间里是否有连续$w$个围栏的高度大于等于这个答案。
因为答案肯定是出现过的高度这个性质,那么可以考虑以高度建一棵可持久化线段树,先将高度数组离散化排好序,第$i$个版本的线段树代表的是下标位置的围栏的高度是否大于等于$h_i$,然后保存区间前缀最长连续1、后缀最长连续1、区间最长连续1。第$i$个版本由第$i-1$个版本再加上几个单点修改得来。
查询就保存区间最长前缀及最长后缀进行合并,合并过程更新一下答案。
说起来容易想起来难。我菜爆了。

#include <bits/stdc++.h>
using namespace std; const int N = 1e5 + ;
int n, a[N], h[N], root[N], tol, ans;
vector<int> G[N]; struct Seg {
struct Tree {
int lp, rp, len, pre, suf, mx;
} tree[N * ];
inline void pushup(int p) {
tree[p].pre = tree[tree[p].lp].pre + (tree[tree[p].lp].pre == tree[tree[p].lp].len ? tree[tree[p].rp].pre : );
tree[p].suf = tree[tree[p].rp].suf + (tree[tree[p].rp].suf == tree[tree[p].rp].len ? tree[tree[p].lp].suf : );
tree[p].mx = max(tree[tree[p].lp].suf + tree[tree[p].rp].pre, max(tree[tree[p].lp].mx, tree[tree[p].rp].mx));
}
void build(int &p, int l, int r) {
p = ++tol;
tree[p].len = tree[p].pre = tree[p].suf = tree[p].mx = r - l + ;
if (l == r) return;
int mid = l + r >> ;
build(tree[p].lp, l, mid);
build(tree[p].rp, mid + , r);
}
void update(int &p, int q, int l, int r, int pos) {
tree[p = ++tol] = tree[q];
if (l == r) {
tree[p].pre = tree[p].suf = tree[p].mx = ;
return;
}
int mid = l + r >> ;
if (pos <= mid) update(tree[p].lp, tree[q].lp, l, mid, pos);
else update(tree[p].rp, tree[q].rp, mid + , r, pos);
pushup(p);
}
pair<int, int> query(int p, int l, int r, int x, int y) {
if (x <= l && y >= r) {
ans = max(ans, tree[p].mx);
return pair<int, int>(tree[p].pre, tree[p].suf);
}
int mid = l + r >> ;
pair<int, int> L(, ), R(, );
if (x <= mid) L = query(tree[p].lp, l, mid, x, y);
if (y > mid) R = query(tree[p].rp, mid + , r, x, y);
ans = max(ans, L.second + R.first);
return pair<int, int>(L.first + (L.first == tree[tree[p].lp].len ? R.first : ),
R.second + (R.second == tree[tree[p].rp].len ? L.second : ));
}
} seg; int main() {
scanf("%d", &n);
for (int i = ; i <= n; i++)
scanf("%d", &a[i]), h[i] = a[i];
sort(h + , h + + n);
int cnt = unique(h + , h + + n) - h - ;
for (int i = ; i <= n; i++) {
int pos = lower_bound(h + , h + + cnt, a[i]) - h;
G[pos].push_back(i);
}
seg.build(root[], , n);
for (int i = ; i <= cnt; i++) {
root[i] = root[i - ];
for (int x: G[i - ]) {
seg.update(root[i], root[i], , n, x);
}
}
int q;
scanf("%d", &q);
while (q--) {
int x, y, w;
scanf("%d%d%d", &x, &y, &w);
int res = ;
int l = , r = cnt;
while (l <= r) {
int mid = (l + r + ) >> ;
ans = ;
seg.query(root[mid], , n, x, y);
if (ans >= w) l = mid + , res = mid;
else r = mid - ;
}
printf("%d\n", h[res]);
}
return ;
}

Codeforces 484 E. Sign on Fence的更多相关文章

  1. CF&&CC百套计划4 Codeforces Round #276 (Div. 1) E. Sign on Fence

    http://codeforces.com/contest/484/problem/E 题意: 给出n个数,查询最大的在区间[l,r]内,长为w的子区间的最小值 第i棵线段树表示>=i的数 维护 ...

  2. Codeforces 484E Sign on Fence(是持久的段树+二分法)

    题目链接:Codeforces 484E Sign on Fence 题目大意:给定给一个序列,每一个位置有一个值,表示高度,如今有若干查询,每次查询l,r,w,表示在区间l,r中, 连续最长长度大于 ...

  3. Codeforces Round #276 (Div. 1) E. Sign on Fence 二分+主席树

    E. Sign on Fence   Bizon the Champion has recently finished painting his wood fence. The fence consi ...

  4. AC日记——Sign on Fence Codeforces 484e

    E. Sign on Fence time limit per test 4 seconds memory limit per test 256 megabytes input standard in ...

  5. CF 484E - Sign on Fence

    E. Sign on Fence time limit per test 4 seconds memory limit per test 256 megabytes input standard in ...

  6. 【CF484E】Sign on Fence(主席树)

    [CF484E]Sign on Fence(主席树) 题面 懒得贴CF了,你们自己都找得到 洛谷 题解 这不就是[TJOI&HEOI 排序]那题的套路吗... 二分一个答案,把大于答案的都变成 ...

  7. CF484E Sign on Fence && [国家集训队]middle

    CF484E Sign on Fence #include<bits/stdc++.h> #define RG register #define IL inline #define _ 1 ...

  8. Codeforces Round #276 (Div. 1) E. Sign on Fence (二分答案 主席树 区间合并)

    链接:http://codeforces.com/contest/484/problem/E 题意: 给你n个数的,每个数代表高度: 再给出m个询问,每次询问[l,r]区间内连续w个数的最大的最小值: ...

  9. Sign on Fence CodeForces - 484E

    http://codeforces.com/problemset/problem/484/E 题意: 给定一个长度为n的数列,有m次询问,询问形如l r k 要你在区间[l,r]内选一个长度为k的区间 ...

随机推荐

  1. [终极巨坑]golang+vue开发日记【一】,环境搭建篇

    写在前面 这个golang+vue大部分的内容是基于bydmm(橙卡)大佬的视频学来的,我在这里只是做一下个人开发的笔记,就是图一个乐,毕竟我只是个应届毕业生,如果真的要学请:bydmm的b站空间. ...

  2. (原创)如何搭建PLC+上位机监控系统达到成本的最小化?

    以西门子PLC举例; 西门子PLC有几个型号:S7-200SMART,S7-1200,S7-300,S7-400,S7-1500,价格从低到高. 1个项目中要求的IO数量:600点的DI+DO,若干个 ...

  3. C#读写设置修改调整UVC摄像头画面-倾斜

    有时,我们需要在C#代码中对摄像头的倾斜进行读和写,并立即生效.如何实现呢? 建立基于SharpCamera的项目 首先,请根据之前的一篇博文 点击这里 中的说明,建立基于SharpCamera的摄像 ...

  4. Neo私钥到地址

    基础名词 Neo是个区块链工程,地址,公钥,私钥,地址脚本,base58,sha256,ripemd160,ECCsa,secp256k1,secp25r1这些词都是区块链技术相关的,或是新东西或者有 ...

  5. docker搭建elasticsearch、kibana,并集成至spring boot

    步骤如下: 一.基于docker搭建elasticsearch环境 1.拉取镜像 docker pull elasticsearch5.6.8 2.制作elasticsearch的配置文件 maste ...

  6. 30、filter数组去重

    eg: let arr=[1,0,0,9,7,7,5,2] let data=arr.filter((item,index,self)=> self.indexOf(item)===index ...

  7. CSS 初识

    一.CSS 发展历程 从HTML被发明开始,样式就以各种形式存在.不同的浏览器结合它们各自的样式语言为用户提供页面效果的控制.最初的HTML只包含很少的显示属性. 随着HTML的成长,为了满足页面设计 ...

  8. XML简述

    XML简述 本文主要内容都是在中国大学MOOC上学习的,这里做个记录. 课程:Java核心技术(进阶),华东师范大学 陈良育老师 感谢陈良育老师,在他的慕课上受益匪浅. XML基本概念 XML(eXt ...

  9. Nexus6p手机root和安装xposed

    进行root前需要两个前提条件 解锁OEM 进入开发者选项:设置-〉关于-〉一直点版本号会出现,usb调试打开 手机连接pc命令行输入: adb reboot bootloader 进入bootloa ...

  10. 一、MySQL基础知识

    一.背景介绍 我们每天都在访问各种网站.APP,如微信.QQ.抖音,今日头条等,这些东西上面都存在大量的信息,这些信息都需要有地方存储,存储在哪里呢?数据库. 所有我们需要开发一个网站.APP,数据库 ...