BZOJ2221: [Jsoi2009]面试的考验
一句话题意,给定一个序列,询问区间内差值的绝对值的最小值。
这道题之前见过一次,似乎是在一次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]面试的考验的更多相关文章
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 自动化测试面试官:登录或注册时有验证码怎么处理?OCR图像识别技术大揭秘!
本节大纲 读取cookie实现免登陆 pytesseract+tesseract-ocr实现图像识别 Pillow库对验证码截图 API接口实现图像识别 今天的这个技术点,为什么要给大家分享一下呢? ...
- 2018第九届蓝桥杯决赛(C++ B组)
逛了大半个北京还是挺好玩de 第一题 标题:换零钞 x星球的钞票的面额只有:100元,5元,2元,1元,共4种. 小明去x星旅游,他手里只有2张100元的x星币,太不方便,恰好路过x星银行就去换零钱. ...
- python每日经典算法题5(基础题)+1(中难题)
现在,越来越多的公司面试以及考验面试对算法要求都提高了一个层次,从现在,我讲每日抽出时间进行5+1算法题讲解,5是指基础题,1是指1道中等偏难.希望能够让大家熟练掌握python的语法结构已经一些高级 ...
- 2018年蓝桥杯B组C/C++决赛题目
自己的博客排版,自我感觉略好一点. 先放上题目. 点击查看2018年蓝桥杯B组C/C++决赛题目题解 1.换零钞 x星球的钞票的面额只有:100元,5元,2元,1元,共4种. 小明去x星旅游, ...
- Java开发面试
有很多文章说面试相关的问题,有国内也有国外的,但是我相信不少人,特 别是新人看完后还是觉得比较虚比较泛,似乎好像懂了,但是一遇到面试还 是有些手无足措或者重复犯一些错误.本篇文章正是结合实际经 ...
- 脑筋急转弯——Google 面试
1. 村子里有100对夫妻,其中每个丈夫都瞒着自己的妻子偷情...村里的每个妻子都能立即发现除自己丈夫之外的其他男人是否偷情,唯独不知道她自己的丈夫到底有没有偷情.村里的规矩不容忍通奸.任何一个妻子, ...
- 逻辑思维面试题-java后端面试-遁地龙卷风
(-1)写在前面 最近参加了一次面试,对笔试题很感兴趣,就回来百度一下.通过对这些题目的思考让我想起了建模中的关联,感觉这些题如果没接触就是从0到1,考验逻辑思维的话从1到100会更好,并且编程简易模 ...
- 面试官的七种武器:Java篇
起源 自己经历过的面试也不少了,互联网的.外企的,都有.总结一下这些面试的经验,发现面试官问的问题其实不外乎几个大类,玩不出太多新鲜玩意的.细细想来,面试官拥有以下七种武器.恰似古龙先生笔下的武侠世界 ...
随机推荐
- codeblocks中cocos2dx项目添加新的.cpp和.h文件后编译运行的方法
新建了cocos2dx项目后(比如我这里建立的项目名为Test01),项目目录下有如下目录和文件: bin CMakeLists.txt MyGame.layout proj.win10 Classe ...
- 上传图片Security Error
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjIAAACXCAIAAACA4CZ6AAAgAElEQVR4nOy96Xcd13UnugFSUrJer/ ...
- 【MySQL】查询时强制区分大小写的方法
MySQL默认的查询也不区分大小写.但作为用户信息,一旦用户名重复,又会浪费很多资源.再者,李逵.李鬼的多起来,侦辨起来很困难.要做到这一点,要么在建表时,明确大小写敏感(字段明确大小写敏感) sql ...
- 【Twitter接口】网站嵌入推特信息
提示:要 翻 墙 的,墙内的去玩新浪微博吧 方法 1 打开链接: https://publish.twitter.com ,输入链接.在下边选择时间表格式 复制这段代码.粘贴到你的网站,就可以使 ...
- linux 学习的一些书单,对了解android 也有大用
要推荐的书,我在<那两年炼就的Android内功修养>这篇文章中有提到,这里再列一下出来: 语言类: <深度探索C++对象模型>,对应的英文版是<Inside C+++ ...
- css 分栏高度自动相等
方法2: <div class="ticket_table"> <div class="ticket_l"> <h3>全票& ...
- 使用MySQLMTOP监控MySQL性能(一)
一.环境说明 1.服务器角色 服务器角色 172.18.35.29 10.160.22.14 (MySQL Master) 10.160.22.47 (MySQL Slave) 监控点 YES NO ...
- postgresql----UNION&&INTERSECT&&EXCEPT
多个SELECT语句可以使用UNION,INTERSECT和EXCEPT进行集合处理,其中UNION用于求并集,INTERSECT用于求交集,EXCEPT用于求差集.用法如下 query1 UNION ...
- javascript飞机大战-----009游戏结束
/* 游戏引擎 */ var Engine = { //刚开始的游戏状态 gameStatus:false, //所以敌机 enemy:{}, //子弹 bullet:{}, //得分 scroe:0 ...
- Ora-1157 ora-1110错误解决案例一枚
1.数据库打开报错如下: SQL> alter database open; alter database open * ERROR at line 1: ORA-01157: cannot i ...