Codeforces 765F Souvenirs
Artsem is on vacation and wants to buy souvenirs for his two teammates. There are n souvenir shops along the street. In i-th shop Artsem can buy one souvenir for ai dollars, and he cannot buy more than one souvenir in one shop. He doesn't want to introduce envy in his team, so he wants to buy two souvenirs with least possible difference in price.
Artsem has visited the shopping street m times. For some strange reason on the i-th day only shops with numbers from li to ri were operating (weird? yes it is, but have you ever tried to come up with a reasonable legend for a range query problem?). For each visit, Artsem wants to know the minimum possible difference in prices of two different souvenirs he can buy in the opened shops.
In other words, for each Artsem's visit you should find the minimum possible value of |as - at| where li ≤ s, t ≤ ri, s ≠ t.
The first line contains an integer n (2 ≤ n ≤ 105).
The second line contains n space-separated integers a1, ..., an (0 ≤ ai ≤ 109).
The third line contains the number of queries m (1 ≤ m ≤ 3·105).
Next m lines describe the queries. i-th of these lines contains two space-separated integers li and ri denoting the range of shops working on i-th day (1 ≤ li < ri ≤ n).
Print the answer to each query in a separate line.
8
3 1 4 1 5 9 2 6
4
1 8
1 3
4 8
5 7
0
1
1
3
树套树 线段树+set 脑洞题
将询问按右端点从小到大排序。从左向右扫描,每次用当前点x更新从1到x位置的答案,然后回答所有右端点在x的询问。
我们可以用线段树更新每个位置答案的时候,这样复杂度显然比暴力更……劣了(可能需要遍历每个位置)。
不过我们可以给线段树加一些剪枝。当用a[x]更新区间[L,R]的时候,设当前最优答案是nowans 如果[L,R]区间内没有在a[x]-nowans ~ a[x]+nowans范围内的数,就不往深层更新了。
如何查找线段树区间内有哪些数?结点上挂个平(s)衡(e)树(t)即可。
↑为了让这个剪枝正确,更新的时候必须先更新线段树右区间再更新左区间。
/*by SilverN*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<set>
using namespace std;
const int INF=1e9;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
struct node{
int f;
set<int>st;
}t[mxn<<];
int a[mxn];
set<int>::iterator it,it2;
struct query{
int L,R;
int id;
bool operator < (const query &b)const{
return (R==b.R && L<b.L) || R<b.R;
}
}q[mxn];
int ans[mxn];
int n,Q;
#define ls rt<<1
#define rs rt<<1|1
void Build(int l,int r,int rt){
t[rt].f=INF;
for(int i=l;i<=r;i++)t[rt].st.insert(a[i]);
if(l==r)return;
int mid=(l+r)>>;
Build(l,mid,ls);Build(mid+,r,rs);
it=t[rt].st.begin();
it2=it;it2++;
for(;it2!=t[rt].st.end();it++,it2++){
t[rt].f=min(t[rt].f,abs(*it2-*(it)));
}
return;
}
int query(int L,int R,int l,int r,int rt){
// printf("L:%d R:%d l:%d r:%d rt:%d f:%d\n",L,R,l,r,rt,t[rt].f);
if(L<=l && r<=R)return t[rt].f;
int mid=(l+r)>>;int res=INF;
if(L<=mid)res=min(res,query(L,R,l,mid,ls));
if(R>mid)res=min(res,query(L,R,mid+,r,rs));
return res;
}
int nowans;
void update(int pos,int v,int l,int r,int rt){
if(l==r){
nowans=min(nowans,abs(a[l]-v));
t[rt].f=min(t[rt].f,nowans);
}
it=t[rt].st.lower_bound(v);
if(it!=t[rt].st.begin()){it2=it;it2--;}
if((it==t[rt].st.begin() || *(it2)<=v-nowans)&&(it==t[rt].st.end() || *(it)>=v+nowans)){
nowans=min(nowans,query(l,r,,n,));
return;
}
int mid=(l+r)>>;
if(pos>mid)
update(pos,v,mid+,r,rs);
update(pos,v,l,mid,ls);
t[rt].f=min(t[ls].f,t[rs].f);
return;
}
void solve(){
int i,j;
int hd=;
for(i=;i<=Q;i++){
while(hd<q[i].R){
nowans=INF; update(hd,a[hd+],,n,); hd++;
}
ans[q[i].id]=query(q[i].L,q[i].R,,n,);
}
for(i=;i<=Q;i++)printf("%d\n",ans[i]);
return;
}
int main(){
int i,j;
n=read();
for(i=;i<=n;i++)a[i]=read();
Q=read();
Build(,n,);
for(i=;i<=Q;i++){
q[i].L=read();q[i].R=read();q[i].id=i;
}
sort(q+,q+Q+);
solve();
return ;
}
Codeforces 765F Souvenirs的更多相关文章
- Codeforces 765F Souvenirs - 莫队算法 - 链表 - 线段树
题目传送门 神速的列车 光速的列车 声速的列车 题目大意 给定一个长度为$n$的序列,$m$次询问区间$[l, r]$内相差最小的两个数的差的绝对值. Solution 1 Mo's Algorith ...
- Codeforces 765F Souvenirs 线段树 + 主席树 (看题解)
Souvenirs 我们将询问离线, 我们从左往右加元素, 如果当前的位置为 i ,用一棵线段树保存区间[x, i]的答案, 每次更新完, 遍历R位于 i 的询问更新答案. 我们先考虑最暴力的做法, ...
- Codeforces.765F.Souvenirs(主席树)
题目链接 看题解觉得非常眼熟,总感觉做过非常非常类似的题啊,就是想不起来=v=. 似乎是这道...也好像不是. \(Description\) 给定长为\(n\)的序列\(A_i\).\(m\)次询问 ...
- 【codeforces 765F】 Souvenirs
http://codeforces.com/problemset/problem/765/F (题目链接) 题意 给出$n$个数的序列,$m$次询问,每次查询区间$[l,r]$之间相差最小的两个数的差 ...
- 【codeforces 765F】Souvenirs
Description Artsem is on vacation and wants to buy souvenirs for his two teammates. There are n souv ...
- Souvenirs CodeForces - 765F (好题)
大意: 给定序列$a$, $m$个询问$[l,r]$, 回答$[l,r]$内最接近的两个数的差. 考虑离线, 枚举右端点, 每个点维护左端点的贡献, 对于新添一个点$a_r$, 只考虑左侧点比$a_r ...
- codeforces选做
收录了最近本人完成的一部分codeforces习题,不定期更新 codeforces 1132E Knapsack 注意到如果只使用某一种物品,那么这八种物品可以达到的最小相同重量为\(840\) 故 ...
- Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) F. Souvenirs 线段树套set
F. Souvenirs 题目连接: http://codeforces.com/contest/765/problem/F Description Artsem is on vacation and ...
- CodeForces 765 F Souvenirs 线段树
Souvenirs 题意:给你n个数, m次询问, 对于每次一次询问, 求出询问区间内绝对值差值的最小值. 题解:先按查询的右端点从小到大sort一下,然后对于塞入一个数的时候, 就处理出所有左端点到 ...
随机推荐
- keepalived 高可用(IP飘移)
什么是keepalived? keepalived是一个在c中编写的路由软件,该项目的主要目标是为Linux系统和基于Linux的基础架构提供简单和强大的设备,用于loadbalance和高可用性.l ...
- Java实现的词频统计
要求: 1.读取文件: 2.记录出现的词汇及出现频率: 3.按照频率降序排列: 4.输出结果. 概要: 1.读取的文件路径是默认的,为了方便调试,将要统计的文章.段落复制到文本中即可:2.只支持英文: ...
- PHP创建对象的几种形式
创建对象的几种形式 class C1{ var $p1 = 1; //定义一个属性: } 形式1: $o1 = new C1(); //通过一个类,去new出一个对象 形式2: $o2 = new ...
- apache server-status配置
引言 自己配置LAMP服务器时(xwamp),获取状态信息出现错误: You don't have permission to access /server-status on this server ...
- Codeforces 618D Hamiltonian Spanning Tree(树的最小路径覆盖)
题意:给出一张完全图,所有的边的边权都是 y,现在给出图的一个生成树,将生成树上的边的边权改为 x,求一条距离最短的哈密顿路径. 先考虑x>=y的情况,那么应该尽量不走生成树上的边,如果生成树上 ...
- bzoj3477[Usaco2014 Mar]Sabotage
题意 给出一个长为n的正整数序列(n<=1e5),要求选出一个非空前缀和一个非空后缀(这两段不能够加起来组成整个序列),使得这个前缀和后缀中的所有数字一起求平均数的结果最小 分析 最大/最小化平 ...
- 【JavaScript&jQuery】前端资源大全
综合类 综合类 地址 前端知识体系 http://www.cnblogs.com/sb19871023/p/3894452.html 前端知识结构 https://github.com/Jackson ...
- "XX cannot be resolved to a type "eclipse报错及解决
好久都没有写博了,还记得自己准备考研,结果你会发现——你永远不知道,你将会走上哪个路. 长远的目标是好的,但有些时候身不由己也迫不得已!做好自己的当下就是好的. 不论搞什么,总会遇到各种各样的问题,以 ...
- PyCharm入门教程——在编辑器中打开和重新打开文件
PyCharm最新版本下载 JetBrains PyCharm是一种Python IDE,其带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具.此外,该IDE提供了一些高级功能,以用于 ...
- Redis学习笔记一:Redis安装
Redis安装 1.下载进入redis官网下载redis-xxx.tar.gz包 2.将redis-xxx.tar.gz拷贝到Linux某一目录下并对其进行解压 tar -zxvf Redis-xxx ...