传送门

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

这道题之前见过一次,似乎是在一次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. 详谈redis优化配置和redis.conf

    1. Redis.conf 配置参数: #是否作为守护进程运行 daemonize yes #如以后台进程运行,则需指定一个pid,默认为/var/run/redis.pid pidfile redi ...

  2. 【七牛云】时间戳防盗链鉴权php实现

    基于时间戳防盗链的功能其实每家的CDN都是支持的.主要是通过使用约定的加密字符串来对具有访问有效期的资源链接进行一些加密计算的到一个sign值,然后访问外链里面带上这个sign和截止时间戳去访问CDN ...

  3. MQTT协议笔记之mqtt.io项目TCP协议支持

    前言 MQTT定义了物联网传输协议,其标准倾向于原始TCP实现.构建于TCP的上层协议堆栈,诸如HTTP等,在空间上多了一些处理路径,稍微耗费了CPU和内存,虽看似微乎其微,但对很多处理能力不足的嵌入 ...

  4. 2012Noip提高组Day2 T3 疫情控制

    题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到 ...

  5. 使用Eclipse(以及intellij IDEA)配合JDWP对服务器上部署的代码进行调试

    今天遇到了一个问题:同样的代码,在服务器上跑的时候会报空指针异常,但是在本地是没有问题的,看服务器上打印的日志只能看到异常信息,不能准确地定位到出问题的代码,于是就搜索了一下远程调试.结果还真的可以在 ...

  6. DCloud开发资源链接

    jQuery链接: <script src='http://libs.baidu.com/jquery/1.8.3/jquery.min.js'></script> HTML5 ...

  7. JAVA学习基础知识总结(原创)

    (未经博主允许,禁止转载!) 一.基础知识:1.JVM.JRE和JDK的区别: JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性. java语言是跨平 ...

  8. mysql数据库多源复制方案

    概述 由于目前生产环境的mysql数据库分布在两台服务器,若从单一主从来看,配置很简单,但是需要将两台服务器的数据库同步到一台从库上面,需要进行更多配置和注意事项.多源复制有两种方案,Binlog+P ...

  9. HOJ 2139 Spiderman's workout(动态规划)

    Spiderman's workout My Tags (Edit) Source : Nordic Collegiate Programming Contest 2003 Time limit : ...

  10. php5.6 的curl开启和之前的不太一样了,搞了半天,记录下

    设置电脑环境变量中的->系统变量(注:不是用户变量) 新建 PHP_HOME 值 D:\php /PHP 根目录 Path 增加 ;%PHP_HOME%;%PHP_HOME%\ext       ...