问题描述

Lxy养了N头奶牛,他把N头奶牛用1..N编号,第i头奶牛编号为i。为了让奶牛多产奶,每天早上他都会让奶牛们排成一排做早操。奶牛们是随机排列的。在奶牛排列中,如果一段区间[L,R]中的数从小到大排列后是连续的,他认为这段区间是优美的。比如奶牛排列为:(3, 1, 7, 5, 6, 4, 2),区间[3,6]是优美的,它包含4,5,6,7连续的四个数,而区间[1,3] 是不优美的。Lxy的问题是:对于给定的一个区间[L,R](1<=L<=R<=N), 他想知道,包含区间[L,R]的最短优美区间,比如区间[1,3]的最短优美区间是[1,7]。

输入

第一行为一个整数N,表示奶牛的个数。

第二行为1到N的一个排列,表示奶牛的队伍。

第三行为一个整数M,表示有M个询问。

后面有M行,每行有两个整数L,R表示询问区间。

输出

输出为M行,每行两个整数,表示包含询问区间的最短优美区间。

输入输出样例

样例1

input

7

3 1 7 5 6 4 2

3

3 6

7 7

1 3

output

3 6

7 7

1 7

样例2

input

10

2 1 4 3 5 6 7 10 8 9

5

2 3

3 7

4 7

4 8

7 8

output

1 4

3 7

3 7

3 10

7 10

数据范围

15%的数据满足: 1 <=N,M <= 15;

50%的数据满足:1 <=N,M <= 1000。

100%的数据满足:1 <=N,M <= 100000。

解析

为了给出题人留面子,不让他被骂出个题只有一种解法而且只有满分解法,我先给个80分做法。

预处理一个数组pos[i],表示数i在原数组的位置(第几个数)。

在询问区间内找一个最小值和最大值,作为新的l和r,新的l和r作为一个询问区间,在pos数组里找一个最小值和最大值,他们再作为新的l和r,形成询问区间,在原数组寻找最小值和最大值,并再次重复刚才的操作……

上述过程可能很无脑很中二,然而这就是模拟题意找出答案的过程。

最大值最小值用st表预处理,一共四个st表,比线段树好写……

那么……

正解是分治,像归并排序那样。

不断求[l,mid] [mid+1,r]的优美序列,直到分成[mid,mid+1]

可以证明是正确的。

事实上分治做的熟练的人可能一眼秒这道题。

代码

80pts

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
template<class T>
void read(T &res)
{
res = 0;
T f = 1;
char cc = getchar();
while(cc < '0' || cc > '9')
{
if(cc == '-') f = -1;
cc = getchar();
}
while(cc >= '0' && cc <= '9')
{
res = res * 10 + cc - '0';
cc = getchar();
}
res *= f;
}
const int maxn = 1e5 + 5;
int n,m;
int seqmin[maxn][50];
int posmin[maxn][50];
int seqmax[maxn][50];
int posmax[maxn][50];
int ansl,ansr;
void init()
{
for(int j=1;(1<<j) <= n;j++)
{
for(int i=0;i+(1<<j)-1 <= n;i++)
{
seqmax[i][j] = max(seqmax[i][j-1],seqmax[i+(1<<(j-1))][j-1]); // 1
seqmin[i][j] = min(seqmin[i][j-1],seqmin[i+(1<<(j-1))][j-1]); // 2
posmax[i][j] = max(posmax[i][j-1],posmax[i+(1<<(j-1))][j-1]); // 3
posmin[i][j] = min(posmin[i][j-1],posmin[i+(1<<(j-1))][j-1]); // 4
}
}
}
int query(int l,int r,int ju)
{
int t = int(log((double)(r - l + 1)) / log(2.0));
if(ju == 1)
return max(seqmax[l][t],seqmax[r-(1<<t)+1][t]);
if(ju == 2)
return min(seqmin[l][t],seqmin[r-(1<<t)+1][t]);
if(ju == 3)
return max(posmax[l][t],posmax[r-(1<<t)+1][t]);
if(ju == 4)
return min(posmin[l][t],posmin[r-(1<<t)+1][t]);
}
void change(int inl,int inr)
{
int templ,tempr,endl,endr;
templ = query(inl,inr,2);
tempr = query(inl,inr,1);
endl = query(templ,tempr,4);
endr = query(templ,tempr,3);
if(endl == inl && endr == inr)
{
ansl = endl;
ansr = endr;
return;
}
else
change(endl,endr); }
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
read(n);
for(int i=1;i<=n;i++)
read(seqmin[i][0]),seqmax[i][0] = seqmin[i][0];
for(int i=1;i<=n;i++)
posmax[seqmin[i][0]][0] = i,posmin[seqmin[i][0]][0] = i;
init();
read(m);
while(m--)
{
int l,r;
read(l);read(r);
change(l,r);
printf("%d %d\n",ansl,ansr);
}
return 0;
}

100pts

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=100005;
#define pb push_back
#define lc (o<<1)
#define mid (l+r>>1)
#define rc ((o<<1)|1)
struct ask{
int L,num;
bool operator <(const ask &u)const{
return L<u.L;
}
};
vector<ask> g[N];
multiset<ask> s;
multiset<ask> :: iterator it;
int n,a[N],p[N],mx[N*4],pos[N*4],Q;
int le,ri,w,al[N],ar[N],M,P,tag[N*4];
inline void mt(int o){
mx[o]=max(mx[lc],mx[rc]);
pos[o]=(mx[rc]==mx[o]?pos[rc]:pos[lc]);
}
inline void work(int o,int der){ tag[o]+=der,mx[o]+=der;}
inline void pd(int o){ if(tag[o]) work(lc,tag[o]),work(rc,tag[o]),tag[o]=0;}
void build(int o,int l,int r){
mx[o]=r,pos[o]=r;
if(l==r) return;
build(lc,l,mid),build(rc,mid+1,r);
}
void update(int o,int l,int r){
if(l>=le&&r<=ri){ work(o,w); return;}
pd(o);
if(le<=mid) update(lc,l,mid);
if(ri>mid) update(rc,mid+1,r);
mt(o);
}
void query(int o,int l,int r){
if(l>=le&&r<=ri){ if(mx[o]>M) M=mx[o],P=pos[o]; return;}
pd(o);
if(ri>mid) query(rc,mid+1,r);
if(le<=mid) query(lc,l,mid);
}
inline bool can(int cc){
le=1,ri=it->L,M=P=0;
query(1,1,n);
if(M==cc){ al[it->num]=P,ar[it->num]=cc; return 1;}
return 0;
}
inline void solve(){
build(1,1,n),w=1;
ask inf=(ask){233333,0};
for(int i=1;i<=n;i++){
for(ask x:g[i]) s.insert(x);
ri=p[a[i]-1],le=1;
if(ri&&ri<i) update(1,1,n);
ri=p[a[i]+1],le=1;
if(ri&&ri<i) update(1,1,n);
for(;s.size();s.erase(it)){
it=--s.lower_bound(inf);
if(!can(i)) break;
}
}
}
int main(){
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout); scanf("%d",&n);
for(int i=1;i<=n;i++) {
scanf("%d",&a[i]);
p[a[i]]=i;
};
scanf("%d",&Q);
for(int i=1,l,r;i<=Q;i++){
scanf("%d %d",&l,&r);
g[r].pb((ask){l,i});
}
solve();
for(int i=1;i<=Q;i++) printf("%d %d\n",al[i],ar[i]);
return 0;
}

优美序列(sequence)的更多相关文章

  1. [JZOJ6279] 2019.8.5【NOIP提高组A】优美序列

    题目 题目大意 给你一个排列以及若干区间,对于每个区间,问包含它的最小的优美序列的区间. 所谓优美序列,即将权值排序后能够得到连续的排列. 思考历程 优美序列显然满足这个条件:\(mx-mn=r-l\ ...

  2. Oracle新表使用序列(sequence)作为插入值,初始值不是第一个,oraclesequence

    Oracle新表使用序列(sequence)作为插入值,初始值不是第一个,oraclesequence 使用oracle11g插入数据时遇到这样一个问题: 1 --创建测试表-- 2 CREATE T ...

  3. Oracle序列(Sequence)创建、使用、修改、删除

    Oracle对象课程:序列(Sequence)创建.使用.修改.删除,序列(Sequence)是用来生成连续的整数数据的对象.序列常常用来作为主键中增长列,序列中的可以升序生成,也可以降序生成.创建序 ...

  4. 序列sequence中的cache问题

    Oracle中序列Sequence的创建语法如下: CREATE SEQUENCE [ schema. ] sequence [ { INCREMENT BY | START WITH } integ ...

  5. oracle数据库--序列(sequence)

    一个问题: 在某张表中,存在一个id列(整数),我们希望在添加记录的时候,该列从1开始,自动的增长,怎么处理? 解决方式:oracle是利用"序列"(sequence)来完成的. ...

  6. Oracle数据库中序列(SEQUENCE)的用法详解

    Oracle数据库中序列(SEQUENCE)的用法详解   在Oracle数据库中,序列的用途是生成表的主键值,可以在插入语句中引用,也可以通过查询检查当前值,或使序列增至下一个值.本文我们主要介绍了 ...

  7. Oracle 序列(sequence)

    序列(sequence) 是Oracle提供的用于生成一系列唯一数字的数据库对象.它会自动生成顺序递增或者递减的序列号,以实现自动提供唯一的主键值.序列可以在多用户并发环境中使用,并且可以为所有用户生 ...

  8. oracle 序列sequence

    查询所有的序列: select 'create sequence '||sequence_name|| ' minvalue '||min_value|| ' maxvalue '||max_valu ...

  9. 序列(SEQUENCE)

    序列(SEQUENCE)是序列号生成器,可以为表中的行自动生成序列号,产生一组等间隔的数值(类型为数字).其主要的用途是生成表的主键值,可以在插入语句中引用,也可以通过查询检查当前值,或使序列增至下一 ...

随机推荐

  1. 新的blog站地址

    自己用Jekyll搭建了一个静态blog网站 以后的blog随笔就更新在:https:/blog.hudunsec.cn

  2. 使用keil5,加断点调试后,停止运行的问题

    加上断点调试,执行到断点的时就出现程序停止运行的提示. 原因:是工程路径存放太深.

  3. Vsftpd服务重启、暂停命令

    VSFTP是一个基于GPL发布的类Unix系统上使用的FTP服务器软件,它的全称是Very Secure FTP 从此名称可以看出来,编制者的初衷是代码的安全. 在使用Vsftp服务是经常需要启动.停 ...

  4. iOS Simulator version 11 or later is currently not supported.

    iOS Simulator version 11 or later is currently not supported.You can open Xcode > Preferences > ...

  5. samba实现CentOS和window上的数据同步

    前言 之前做了一个项目,需要写python脚本来修改组件的安装方式,脚本是在windows下面的pycharm下面进行编写,但是编译要在linux上面进行分模块的maven编译,虽然之前也写了pych ...

  6. <mvc:resources mapping="/xxx/**" location="/xxx/"/>无效,可能和Controller的URL模式有关

    某项目webapp下有子目录res,其中有img.css.js等存放静态资源的文件夹. 在定义了dispacher-servlet的<url-pattern>/</url-patte ...

  7. BitmapData.threshold()方法

    import flash.display.Bitmap; import flash.display.BitmapData; import flash.geom.Rectangle; import fl ...

  8. 关于Eclipse for Python

    学习Python一段时间,一直用Python的IDE进行开发,过程蛮顺利,但是,基于Visual Studio的使用经验,就希望尝试一种更友好的,更方便管理项目的IDE,分别尝试了PyCharm和Ec ...

  9. 【译】为什么BERT有3个嵌入层,它们都是如何实现的

    目录 引言 概览 Token Embeddings 作用 实现 Segment Embeddings 作用 实现 Position Embeddings 作用 实现 合成表示 结论 参考文献 本文翻译 ...

  10. TCP连接笔记

    每个socket套接字都有一个引用计数. 调用close时只是将相应的引用计数减1. 只有当引用计数为0时才会真正的清理套接字资源,也就是发送FIN. 若只是想在某个TCP连接上发送一个FIN可以改用 ...