传送门

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

这道题之前见过一次,似乎是在一次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. codeblocks中cocos2dx项目添加新的.cpp和.h文件后编译运行的方法

    新建了cocos2dx项目后(比如我这里建立的项目名为Test01),项目目录下有如下目录和文件: bin CMakeLists.txt MyGame.layout proj.win10 Classe ...

  2. 上传图片Security Error

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjIAAACXCAIAAACA4CZ6AAAgAElEQVR4nOy96Xcd13UnugFSUrJer/ ...

  3. 【MySQL】查询时强制区分大小写的方法

    MySQL默认的查询也不区分大小写.但作为用户信息,一旦用户名重复,又会浪费很多资源.再者,李逵.李鬼的多起来,侦辨起来很困难.要做到这一点,要么在建表时,明确大小写敏感(字段明确大小写敏感) sql ...

  4. 【Twitter接口】网站嵌入推特信息

    提示:要 翻 墙 的,墙内的去玩新浪微博吧 方法 1  打开链接:  https://publish.twitter.com  ,输入链接.在下边选择时间表格式 复制这段代码.粘贴到你的网站,就可以使 ...

  5. linux 学习的一些书单,对了解android 也有大用

    要推荐的书,我在<那两年炼就的Android内功修养>这篇文章中有提到,这里再列一下出来: 语言类: <深度探索C++对象模型>,对应的英文版是<Inside C+++  ...

  6. css 分栏高度自动相等

    方法2: <div class="ticket_table"> <div class="ticket_l"> <h3>全票& ...

  7. 使用MySQLMTOP监控MySQL性能(一)

    一.环境说明 1.服务器角色 服务器角色 172.18.35.29 10.160.22.14 (MySQL Master) 10.160.22.47 (MySQL Slave) 监控点 YES NO ...

  8. postgresql----UNION&&INTERSECT&&EXCEPT

    多个SELECT语句可以使用UNION,INTERSECT和EXCEPT进行集合处理,其中UNION用于求并集,INTERSECT用于求交集,EXCEPT用于求差集.用法如下 query1 UNION ...

  9. javascript飞机大战-----009游戏结束

    /* 游戏引擎 */ var Engine = { //刚开始的游戏状态 gameStatus:false, //所以敌机 enemy:{}, //子弹 bullet:{}, //得分 scroe:0 ...

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

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