$ \color{#0066ff}{ 题目描述 }$

A县旁,连绵着一条长度为 n 的山脉,这条山脉由 n 座山峰组成,第 i 座山

峰的高度为 ai。作为著名的旅游县城,每天来到山脉游玩的旅客络绎不绝。但当

游客们去过了第一座山之后,就必须要先下山,再上第二座山。这实在是件很麻

烦的事,于是人们计划在山峰之间修建一些桥梁。

修建桥梁是件很麻烦的事。因为如果两座山峰的高度差太大的话,再在这两

座之间修建桥梁就显得有些不合适了。设计者们给出了 m 个计划,每个计划会

从区间\([l,r]\) 中选择两座山峰,搭建桥梁。为了方便建设,他们会选择高度差最

小的一组进行施工。他们想知道,这个最小的高度差是多少。

\(\color{#0066ff}{输入格式}\)

第丬行一个整数 n 表示山脉的长度。

第二行 n 个整数 ai,表示每个山峰的高度。

第三行一个整数 m 表示计划桥梁修建的数量。

接下来的 m 行,每行两个整数l, r,表示将在区间 \([l, r]\) 内修建仺座桥梁。

\(\color{#0066ff}{输出格式}\)

共 m 行。每行一个整数表示桥梁的构小高度差。

\(\color{#0066ff}{输入样例}\)

8
3 1 4 1 5 9 2 6
4
1 8
1 3
4 8
5 7

\(\color{#0066ff}{输出样例}\)

0
1
1
3

\(\color{#0066ff}{数据范围与提示}\)

$ 2<=n<=10^{5} ,0<=a_{i}<=10^{9} 1<=m<=3*10^5$

\(\color{#0066ff}{题解}\)

#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int inf = 0x7fffffff;
const int maxn = 1e6 + 10;
struct SGT {
protected:
struct node {
int l, r;
node *ch[2];
int val, min;
node(int l = 0, int r = 0, int val = inf, int min = inf): l(l), r(r), val(val), min(min) { ch[0] = ch[1] = NULL; }
int mid() { return (l + r) >> 1; }
void trn(int v) { min = std::min(min, v), val = std::min(val, v); }
void dwn() {
if(min == inf) return;
ch[0]->trn(min), ch[1]->trn(min);
min = inf;
}
void upd() { val = std::min(ch[0]->val, ch[1]->val); }
}*root, pool[maxn * 4], *tail;
void build(node *&o, int l, int r) {
o = new(tail++) node(l, r);
if(l == r) return;
build(o->ch[0], l, o->mid());
build(o->ch[1], o->mid() + 1, r);
}
void lazy(node *o, int l, int r, int val) {
if(l > r) return;
if(l <= o->l && o->r <= r) return o->trn(val);
o->dwn();
if(l <= o->mid()) lazy(o->ch[0], l, r, val);
if(r > o->mid()) lazy(o->ch[1], l, r, val);
o->upd();
}
public:
SGT() { root = NULL; }
void init(int n) { tail = pool; build(root, 1, n); }
int query(int pos) {
node *o = root;
while(o->l != o->r) o->dwn(), o = o->ch[pos > o->mid()];
return o->val;
}
void lazy(int l, int r, int val) {
lazy(root, l, r, val);
}
}s;
struct node {
node *ch[2];
int pos, num;
node(int pos = 0, int num = 0): pos(pos), num(num) { ch[0] = ch[1] = NULL; }
void upd() { pos = std::max(ch[0]->pos, ch[1]->pos); }
}*root[maxn], pool[maxn * 8], *tail = pool;
struct question {
int l, r, id;
friend bool operator < (const question &a, const question &b) {
return a.r < b.r;
}
}e[maxn];
int ans[maxn];
void init() {
root[0] = new node();
root[0]->ch[0] = root[0]->ch[1] = root[0];
}
int n, m, a[maxn];
void add(node *&o, node *lst, int l, int r, int pos, int id) {
o = new(tail++) node(); *o = *lst, o->num++;
if(l == r) return (void)(o->pos = id);
int mid = (l + r) >> 1;
if(pos <= mid) add(o->ch[0], lst->ch[0], l, mid, pos, id);
else add(o->ch[1], lst->ch[1], mid + 1, r, pos, id);
o->upd();
}
int query(node *o, int l, int r, int ql, int qr) {
if(ql > qr) return -1;
if(!o->num) return -1;
if(ql <= l && r <= qr) return o->pos;
int mid = (l + r) >> 1, ans = -1;
if(ql <= mid) ans = std::max(ans, query(o->ch[0], l, mid, ql, qr));
if(qr > mid) ans = std::max(ans, query(o->ch[1], mid + 1, r, ql, qr));
return ans;
}
int main() {
s.init(n = in()), init();
for(int i = 1; i <= n; i++) add(root[i], root[i - 1], 1, 1e9, a[i] = in(), i);
int m = in();
for(int i = 1; i <= m; i++) e[i].l = in(), e[i].r = in(), e[i].id = i;
std::sort(e + 1, e + m + 1);
int now = 1;
for(int i = 1; i <= n; i++) {
int nowpos = query(root[i - 1], 1, 1e9, a[i], 1e9);
while(~nowpos) {
s.lazy(1, nowpos, a[nowpos] - a[i]);
nowpos = query(root[nowpos - 1], 1, 1e9, a[i], ((a[i] + a[nowpos]) / 2));
}
while(now <= m && e[now].r == i) {
ans[e[now].id] = s.query(e[now].l);
now++;
}
}
s.init(n);
now = 1;
for(int i = 1; i <= n; i++) {
int nowpos = query(root[i - 1], 1, 1e9, 1, a[i] - 1);
while(~nowpos) {
s.lazy(1, nowpos, a[i] - a[nowpos]);
nowpos = query(root[nowpos - 1], 1, 1e9, ((a[i] + a[nowpos]) / 2), a[i] - 1);
}
while(now <= m && e[now].r == i) {
ans[e[now].id] = std::min(ans[e[now].id], s.query(e[now].l));
now++;
}
}
for(int i = 1; i <= m; i++) printf("%d\n", ans[i]);
return 0;
}
/*
11
3 1 4 1 5 9 2 6 5 3 5
5
1 3
1 8
5 7
6 8
10 11
*/

CF765F Souvenirs 离线+线段树+主席树的更多相关文章

  1. 线段树简单入门 (含普通线段树, zkw线段树, 主席树)

    线段树简单入门 递归版线段树 线段树的定义 线段树, 顾名思义, 就是每个节点表示一个区间. 线段树通常维护一些区间的值, 例如区间和. 比如, 上图 \([2, 5]\) 区间的和, 为以下区间的和 ...

  2. Codeforces 765F Souvenirs 线段树 + 主席树 (看题解)

    Souvenirs 我们将询问离线, 我们从左往右加元素, 如果当前的位置为 i ,用一棵线段树保存区间[x, i]的答案, 每次更新完, 遍历R位于 i 的询问更新答案. 我们先考虑最暴力的做法, ...

  3. 牛客网 暑期ACM多校训练营(第一场)J.Different Integers-区间两侧不同数字的个数-离线树状数组 or 可持久化线段树(主席树)

    J.Different Integers 题意就是给你l,r,问你在区间两侧的[1,l]和[r,n]中,不同数的个数. 两种思路: 1.将数组长度扩大两倍,for(int i=n+1;i<=2* ...

  4. 小结:线段树 & 主席树 & 树状数组

    概要: 就是用来维护区间信息,然后各种秀智商游戏. 技巧及注意: 一定要注意标记的下放的顺序及影响!考虑是否有叠加或相互影响的可能! 和平衡树相同,在操作每一个节点时,必须保证祖先的tag已经完全下放 ...

  5. 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))

    函数式线段树..资瓷 区间第K极值查询 似乎不过似乎划分树的效率更优于它,但是如果主席树套树状数组后,可以处理动态的第K极值.即资瓷插入删除,划分树则不同- 那么原理也比较易懂: 建造一棵线段树(权值 ...

  6. 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题

    “队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄>     线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...

  7. UOJ#218. 【UNR #1】火车管理 线段树 主席树

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ218.html 题解 如果我们可以知道每次弹出栈之后新的栈顶是什么,那么我们就可以在一棵区间覆盖.区间求和 ...

  8. Luogu5289 十二省联考2019字符串问题(后缀数组+拓扑排序+线段树/主席树/KDTree)

    先考虑80分做法,即满足A串长度均不小于B串,容易发现每个B串对应的所有A串在后缀数组上都是一段连续区间,线段树优化连边然后判环求最长链即可.场上就写了这个. 100分也没有什么本质区别,没有A串长度 ...

  9. BZOJ5011 [JXOI2017]颜色 【线段树 + 主席树】

    题目链接 BZOJ5011 题解 一定只有我这种智障会用这么奇怪的方法做这道题.. 由题我们知道最后剩余的一定是一个区间,而且区间内的颜色不存在于区间外 所以我们的目的就是为了找到这样的区间的数量 区 ...

随机推荐

  1. H5(1)

    css布局模型 清楚了CSS 盒模型的基本概念. 盒模型类型, 我们就可以深入探讨网页布局的基本模型了.布局模型与盒模型一样都是 CSS 最基本. 最核心的概念. 但布局模型是建立在盒模型基础之上,又 ...

  2. Java核心技术-接口、lambda表达式与内部类

    本章将主要介绍: 接口技术:主要用来描述类具有什么功能,而并不给出每个功能的具体实现.一个类可以实现一个或多个接口. lambda表达式:这是一种表示可以在将来的某个时间点执行的代码块的简洁方法. 内 ...

  3. 通过snmp监控linux

    一.linux snmpd安装 yum install -y net-snmp net-snmp-utils 二.snmp的配置(vim /etc/snmp/snmpd.conf) com2sec n ...

  4. 解决VirtualBox 上的XP 关机时重启 , 启动时蓝屏 ,点击电源选项蓝屏

    三个问题一次性解决. 启动时的蓝屏显示错误信息是: STOP 0x000000CE (...) DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATION ...

  5. cookie用法小结 cookie.setPath 跨域共享

    1. JSP中Cookie的读写 Cookie的本质是一个键值对,当浏览器访问web服务器的时候写入在客户端机器上,里面记录一些信息.Cookie还有一些附加信息,比如域名.有效时间.注释等等. 下面 ...

  6. MySQL中如何为查询的数据添加自增序号、顺序呢?

    背景介绍 很多时候我们在使用mysql查询数据的时候都会遇到一个问题,就是查询出来了一堆数据,但是查询的数据的表并没有序号,然而部分数据库显示工具是有外带序号显示,但是这种序号不是由sql产生的,而是 ...

  7. 什么是 Java 内存模型,最初它是怎样被破坏的?(转载)

    活跃了将近三年的 JSR 133,近期发布了关于如何修复 Java 内存模型(Java Memory Model, JMM)的公开建议.原始 JMM 中有几个严重缺陷,这导致了一些难度高得惊人的概念语 ...

  8. Android-SDCard外部存储文件读写

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses ...

  9. php以不同名字下载同一个文件(x-sendfile) 【转】

    1.linux 下nginx默认支持x-sendfile模式 Nginx 默认支持该特性,不需要加载额外的模块.需要发送的 HTTP 头为 X-Accel-Redirect.另外,需要在配置文件中做以 ...

  10. 转:javascript判断IE浏览器

    http://blog.csdn.net/ranbolwb/article/details/18555847 function isIE() { //ie? if (!!window.ActiveXO ...