传送门

一句话题意,给定一个序列,询问区间内差值的绝对值的最小值。

这道题之前见过一次,似乎是在一次UER上,那一道题当时是用了近似算法才能过。

数据保证数列随机。

这道题显然非常适合离线的做法,考虑对于没对数来计算贡献。

我们知道在整个序列中一共有$O(N^2)$对数,在所有询问中,有些对的数对询问是无法做出贡献的,考虑如何在离线统计时排除这些数的干扰。

假设一个位置$a_i$,我们考虑$|a_j-a_i|(j<i)$,显然,如果我们能在$a_i$前找到一段递减子序列且$\forall a_j <a_i$,那么这个子序列都会对存在的询问产生贡献。

递增同理。

因为数列随机,我们可以得到这样一个性质:任意$a_i$前的递增/递减序列长度不会超过$logN$。

所以我们维护一颗权值线段树,每次在树上找到坐标最大的点,然后缩小范围再次寻找,这样就保证了递减。

这样的话就可以从左往右扫一遍,再建一颗线段树存答案,把询问按右端点排序后统计答案即可。

//BZOJ2221
//by Cydiater
//2017.2.15
#include <iostream>
#include <queue>
#include <map>
#include <cstring>
#include <string>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <algorithm>
#include <bitset>
#include <set>
#include <vector>
#include <complex>
using namespace std;
#define ll long long
#define up(i,j,n)	for(int i=j;i<=n;i++)
#define down(i,j,n)	for(int i=j;i>=n;i--)
#define cmax(a,b)	a=max(a,b)
#define cmin(a,b)	a=min(a,b)
const int MAXN=5e5+5;
const int oo=2147483647;
inline int read(){
	char ch=getchar();int x=0,f=1;
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int N,M,arr[MAXN],b[MAXN],top,_b[MAXN];
struct Query{
	int x,y,ans,id;
}query[MAXN];
struct SGT{
	struct sgt{
		int tmax,tmin,Max,Min;
	}t[MAXN<<2];
	inline void reload(int root){
		t[root].Max=max(t[root<<1].Max,t[root<<1|1].Max);
		t[root].Min=min(t[root<<1].Min,t[root<<1|1].Min);
	}
	inline void Pushdown(int root){
		int tmax=t[root].tmax,tmin=t[root].tmin;
		t[root].tmax=-1;t[root].tmin=oo;
		if(tmax!=-1){
			cmax(t[root<<1].tmax,tmax);cmax(t[root<<1].Max,tmax);
			cmax(t[root<<1|1].tmax,tmax);cmax(t[root<<1|1].Max,tmax);
		}
		if(tmin!=oo){
			cmin(t[root<<1].tmin,tmin);cmin(t[root<<1].Min,tmin);
			cmin(t[root<<1|1].tmin,tmin);cmin(t[root<<1|1].Min,tmin);
		}
	}
	void Build(int leftt,int rightt,int root,int val){
		t[root].tmax=-1;t[root].tmin=oo;
		if(leftt==rightt){
			t[root].Max=t[root].Min=val;
			return;
		}
		int mid=(leftt+rightt)>>1;
		Build(leftt,mid,root<<1,val);
		Build(mid+1,rightt,root<<1|1,val);
		reload(root);
	}
	int Max(int leftt,int rightt,int root,int L,int R){
		int mid=(leftt+rightt)>>1;
		if(leftt!=rightt)Pushdown(root);
		if(leftt>=L&&rightt<=R)	return t[root].Max;
		if(L<=mid&&mid+1<=R)	return max(Max(leftt,mid,root<<1,L,R),Max(mid+1,rightt,root<<1|1,L,R));
		else if(L<=mid)		return Max(leftt,mid,root<<1,L,R);
		else if(mid+1<=R)	return Max(mid+1,rightt,root<<1|1,L,R);
	}
	int Min(int leftt,int rightt,int root,int L,int R){
		int mid=(leftt+rightt)>>1;
		if(leftt!=rightt)Pushdown(root);
		if(leftt>=L&&rightt<=R)	return t[root].Min;
		if(L<=mid&&mid+1<=R)	return min(Min(leftt,mid,root<<1,L,R),Min(mid+1,rightt,root<<1|1,L,R));
		else if(L<=mid)		return Min(leftt,mid,root<<1,L,R);
		else if(mid+1<=R)	return Min(mid+1,rightt,root<<1|1,L,R);
	}
	void Modify(int leftt,int rightt,int root,int L,int R,int val){
		int mid=(leftt+rightt)>>1;
		if(leftt!=rightt)Pushdown(root);
		if(leftt>=L&&rightt<=R){
			cmax(t[root].Max,val);
			cmin(t[root].Min,val);
			cmax(t[root].tmax,val);
			cmin(t[root].tmin,val);
			return;
		}
		if(L<=mid)		Modify(leftt,mid,root<<1,L,R,val);
		if(mid+1<=R)		Modify(mid+1,rightt,root<<1|1,L,R,val);
		reload(root);
	}
}T1,T2;
namespace solution{
	inline bool cmp(Query x,Query y){return x.y<y.y;}
	inline bool cmpx(Query x,Query y){return x.id<y.id;}
	void Change(int pos){
		int vpos=arr[pos];
		up(L,1,vpos-1){
			int val=T1.Max(1,top,1,L,vpos-1);
			if(val==-oo)break;
			else	T2.Modify(1,N,1,1,val,abs(b[arr[pos]]-b[arr[val]]));
			L=arr[val];
		}
		down(R,top,vpos+1){
			int val=T1.Max(1,top,1,vpos+1,R);
			if(val==-oo)break;
			else T2.Modify(1,N,1,1,val,abs(b[arr[pos]]-b[arr[val]]));
			R=arr[val];
		}
		T1.Modify(1,top,1,vpos,vpos,pos);
	}
	void Prepare(){
		N=read();M=read();
		up(i,1,N)b[i]=arr[i]=read();
		up(i,1,M){
			query[i].x=read();query[i].y=read();query[i].id=i;
		}
		sort(query+1,query+M+1,cmp);
		sort(b+1,b+N+1);
		top=unique(b+1,b+N+1)-(b+1);
		up(i,1,N)arr[i]=lower_bound(b+1,b+top+1,arr[i])-b;
		T1.Build(1,top,1,-oo);
		T2.Build(1,N,1,oo);
	}
	void Solve(){
		int pos=0;
		up(i,1,M){
			int LIM=query[i].y;
			while(pos<LIM)Change(++pos);
			query[i].ans=T2.Min(1,N,1,query[i].x,query[i].y);
		}
		sort(query+1,query+M+1,cmpx);
		up(i,1,M){
			printf("%d\n",query[i].ans);
		}
	}
}
int main(){
	//freopen("input.in","r",stdin);
	using namespace solution;
	Prepare();
	Solve();
	return 0;
}

BZOJ2221: [Jsoi2009]面试的考验的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. 自动化测试面试官:登录或注册时有验证码怎么处理?OCR图像识别技术大揭秘!

    本节大纲 读取cookie实现免登陆 pytesseract+tesseract-ocr实现图像识别 Pillow库对验证码截图 API接口实现图像识别 今天的这个技术点,为什么要给大家分享一下呢? ...

  3. 2018第九届蓝桥杯决赛(C++ B组)

    逛了大半个北京还是挺好玩de 第一题 标题:换零钞 x星球的钞票的面额只有:100元,5元,2元,1元,共4种. 小明去x星旅游,他手里只有2张100元的x星币,太不方便,恰好路过x星银行就去换零钱. ...

  4. python每日经典算法题5(基础题)+1(中难题)

    现在,越来越多的公司面试以及考验面试对算法要求都提高了一个层次,从现在,我讲每日抽出时间进行5+1算法题讲解,5是指基础题,1是指1道中等偏难.希望能够让大家熟练掌握python的语法结构已经一些高级 ...

  5. 2018年蓝桥杯B组C/C++决赛题目

    自己的博客排版,自我感觉略好一点. 先放上题目. 点击查看2018年蓝桥杯B组C/C++决赛题目题解     1.换零钞 x星球的钞票的面额只有:100元,5元,2元,1元,共4种. 小明去x星旅游, ...

  6. Java开发面试

    有很多文章说面试相关的问题,有国内也有国外的,但是我相信不少人,特   别是新人看完后还是觉得比较虚比较泛,似乎好像懂了,但是一遇到面试还   是有些手无足措或者重复犯一些错误.本篇文章正是结合实际经 ...

  7. 脑筋急转弯——Google 面试

    1. 村子里有100对夫妻,其中每个丈夫都瞒着自己的妻子偷情...村里的每个妻子都能立即发现除自己丈夫之外的其他男人是否偷情,唯独不知道她自己的丈夫到底有没有偷情.村里的规矩不容忍通奸.任何一个妻子, ...

  8. 逻辑思维面试题-java后端面试-遁地龙卷风

    (-1)写在前面 最近参加了一次面试,对笔试题很感兴趣,就回来百度一下.通过对这些题目的思考让我想起了建模中的关联,感觉这些题如果没接触就是从0到1,考验逻辑思维的话从1到100会更好,并且编程简易模 ...

  9. 面试官的七种武器:Java篇

    起源 自己经历过的面试也不少了,互联网的.外企的,都有.总结一下这些面试的经验,发现面试官问的问题其实不外乎几个大类,玩不出太多新鲜玩意的.细细想来,面试官拥有以下七种武器.恰似古龙先生笔下的武侠世界 ...

随机推荐

  1. poj_1456 贪心

    题目大意 一家超市,要卖出N种物品(每种物品各一个),每种物品都有一个卖出截止日期Di(在该日期之前卖出可以获得收益,否则就无法卖出),且每种物品被卖出都有一个收益值Pi. 卖出每个物品需要耗时1天, ...

  2. LeetCode——Peeking Iterator

    Description: Given an Iterator class interface with methods: next() and hasNext(), design and implem ...

  3. The 70th problem,UVa10396 Vampire Numbers

    今天看Thinking in Java看到一个吸血鬼数的问题,于是查找UVa里也有类似的问题就动手写了先是用Java写的,不过WA了两次,然后没有发现错误,又用c++写的还是不行.最后发现要排序去重. ...

  4. change事件的兼容性问题

    当input的value被修改时,在没有失去焦点的情况下,无法触发change事件,但是可以触发propertychange事件. 但是propertychange事件存在兼容性问题: IE9以下支持 ...

  5. 关于hql语句的一些问题

    1.student is not mapped问题: 在执行显示数据库数据的时候出错 大概提示说: errors: s.entr_Id student is not mapped 碰到这种情况一般是: ...

  6. 【BZOJ2087】[Poi2010]Sheep 几何+DP

    [BZOJ2087][Poi2010]Sheep Description Lyx的QQ牧场养了很多偶数个的羊,他是Vip,所以牧场是凸多边形(畸形).现在因为他开挂,受到了惩罚,系统要求他把牧场全部分 ...

  7. linux grep命令(linux在文件中搜索内容)

    转自:https://www.cnblogs.com/end/archive/2012/02/21/2360965.html linux grep命令 1.作用Linux系统中grep命令是一种强大的 ...

  8. T-SQL备份数据库恢复

    注:此操作在master数据库上执行 /*1.--得到数据库的文件目录 @dbname 指定要取得目录的数据库名 如果指定的数据不存在,返回安装SQL时设置的默认数据目录 如果指定NULL,则返回默认 ...

  9. Ora-1157 ora-1110错误解决案例一枚

    1.数据库打开报错如下: SQL> alter database open; alter database open * ERROR at line 1: ORA-01157: cannot i ...

  10. redis cluster 集群畅谈(二)

    上一篇http://www.cnblogs.com/qinyujie/p/9029482.html, 主要讲解 redis cluster 集群 搭建,本篇主要讲解实验多master写入.读写分离.实 ...