传送门

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

这道题之前见过一次,似乎是在一次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. String.Join重载String.Join 方法 (String, String[], Int32, Int32)

    https://msdn.microsoft.com/zh-cn/library/tk0xe5h0 String.Join 方法 (String, String[], Int32, Int32) 官方 ...

  2. Change Base

    Given an integer m in base B (2 ≤ B ≤ 10) (m contains no more than 1000 digits), find the value of t ...

  3. cursor:hand & cursor:pointer

    1.cursor:hand & cursor:pointer都是将鼠标设置为手形. 2.cursor:hand存在兼容性问题,firefox并不支持该属性值.但大部分主流浏览器支持cursor ...

  4. Splay模板 1.0

    struct Splay{ int rt,sz; ///根节点,树节点总数 ],fa[N];///值,左右儿子,父亲 void spin(int t){ ///旋转操作 ]==t; son[x][y] ...

  5. 微信小程序 --- page.js文件

    page.js文件是写当前 page.wxml 页面的 JS 脚本文件: 示例: //获取应用实例 const app = getApp() Page({ data: { navComOneOnOff ...

  6. 从零打造在线网盘系统之Struts2框架配置全解析

    欢迎浏览Java工程师SSH教程从零打造在线网盘系统系列教程,本系列教程将会使用SSH(Struts2+Spring+Hibernate)打造一个在线网盘系统,本系列教程是从零开始,所以会详细以及着重 ...

  7. mysql 修改配置文件性能优化

    vim /etc/my.cnf 原配置文件 [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # ...

  8. 全面解析Oracle等待事件的分类、发现及优化

    一.等待事件由来 大家可能有些奇怪,为什么说等待事件,先谈到了指标体系.其实,正是因为指标体系的发展,才导致等待事件的引入.总结一下,Oracle的指标体系,大致经历了下面三个阶段: · 以命中率为主 ...

  9. LINEAR HASH Partitioning

    MySQL :: MySQL 8.0 Reference Manual :: 23.2.4.1 LINEAR HASH Partitioning https://dev.mysql.com/doc/r ...

  10. proxy,https,git,tortoise git,ssh-agent,ssh-add,ssh,ssl,rsync

    看具体应用了,一般的文件复制使用scp,增量同步使用rsync.rsync的认证可以使用ssh,还可以是rsync自己的密码文件. ssh-keygen -l 察看 fineprint 5.1 通过p ...