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一下,然后对于塞入一个数的时候, 就处理出所有左端点到 ...
随机推荐
- nexus在linux上搭建
Maven 仓库的分类:(maven的仓库只有两大类) 1.本地仓库 2.远程仓库,在远程仓库中又分成了3种: 2.1 中央仓库 2.2 私服 2.3 其它公共库 有个maven私服可以很方便地管理我 ...
- Linux下编译程序时,经常会遇到“undefined reference to XXX” 报错,
Linux下编译程序时,经常会遇到“undefined reference to XXX” 报错, 这里总结一些可能的原因和解决方案,给需要的朋友: 说道undefined reference err ...
- webgl 背面剔除
- mybatis 批量插入 返回主键id
我们都知道Mybatis在插入单条数据的时候有两种方式返回自增主键: 1.对于支持生成自增主键的数据库:增加 useGenerateKeys和keyProperty ,<insert>标签 ...
- android Eclipse there no select
点mainactivity类 右键 run as 进行 配置 就可运行
- Nginx LVS HAProxy 对比
一般对负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术.具体的应用需求还得具体分析,如果是中小型的Web应用,比如日PV小于1000万,用Nginx就完全可以了:如果机器不少,可以用D ...
- DNS原理及解析过程
本文主要参考自:http://369369.blog.51cto.com/319630/812889 并做了小幅修改 什么是DNS? 因特网上的主机和人类一样,也可以使用多种方式进行识别.主机的一种识 ...
- Linux下修改环境变量PATH
1.什么是环境变量(PATH) 在Linux中,在执行命令时,系统会按照PATH的设置,去每个PATH定义的路径下搜索执行文件,先搜索到的文件先执行. 我们知道查阅文件属性的指令ls 完整文件名为:/ ...
- 使用cookie保存用户登录信息
写入Cookie HttpCookie _cookie = new HttpCookie("User"); _cookie.Values.Add("UserName&qu ...
- java 集合 父类的使用子类的方法时候 底层自动转型为子类的数据类型
跟继承多态不一样 继承多态需要显示转型