問題描述
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行,每行兩個整數,表示包含詢問區間的最短優美區間。
輸入輸出樣例
樣例一輸入
7
3 1 7 5 6 4 2
3
3 6
7 7
1 3
樣例一輸出
3 6
7 7
1 7
樣例二輸入
10
2 1 4 3 5 6 7 10 8 9
5
2 3
3 7
4 7
4 8
7 8
樣例二輸出
1 4
3 7
3 7
3 10
7 10
數據范圍
15%的數據滿足: 1 <=N,M <= 15;
50%的數據滿足:1 <=N,M <= 1000。
大概是Day最簡單的一道題了
在詢問的區間中找到最大值和最小值,因為要連續,所以中間的值全部要取到,接着找所有要取的值里面最大和最小的位置.
由於這時候沒考慮多包函進來的數字是否都在最開始的區間可以多次用每次詢問出的答案接着詢問,直到詢問和給出的答案相同
ST表和線段樹等log數據結構都能過,不過查詢較多還是ST表更好??
#include<cstdio>
#include<algorithm>
#define ls now<<1
#define rs now<<1|1
using namespace std;
const int MAXN=100002;
const int inf=19260817;
int loc[MAXN],seq[MAXN];
int seqmax[MAXN<<2],seqmin[MAXN<<2];
int locmax[MAXN<<2],locmin[MAXN<<2];
void build(int l,int r,int now)
{
if(l==r){
seqmax[now]=seq[l];
seqmin[now]=seq[l];
locmax[now]=loc[l];
locmin[now]=loc[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,ls);
build(mid+1,r,rs);
seqmax[now]=max(seqmax[ls],seqmax[rs]);
seqmin[now]=min(seqmin[ls],seqmin[rs]);
locmax[now]=max(locmax[ls],locmax[rs]);
locmin[now]=min(locmin[ls],locmin[rs]);
}
int queryseqmax(int l,int r,int ll,int rr,int now)
{
if(ll>rr)return 0;
if(ll>r||rr<l)return 0;
if(l<=ll&&r>=rr)return seqmax[now];
int mid=(ll+rr)>>1;
return max(queryseqmax(l,r,ll,mid,ls),queryseqmax(l,r,mid+1,rr,rs));
}
int querylocmax(int l,int r,int ll,int rr,int now)
{
if(ll>rr)return 0;
if(ll>r||rr<l)return 0;
if(l<=ll&&r>=rr)return locmax[now];
int mid=(ll+rr)>>1;
return max(querylocmax(l,r,ll,mid,ls),querylocmax(l,r,mid+1,rr,rs));
}
int queryseqmin(int l,int r,int ll,int rr,int now)
{
if(ll>rr)return inf;
if(ll>r||rr<l)return inf;
if(l<=ll&&r>=rr)return seqmin[now];
int mid=(ll+rr)>>1;
return min(queryseqmin(l,r,ll,mid,ls),queryseqmin(l,r,mid+1,rr,rs));
}
int querylocmin(int l,int r,int ll,int rr,int now)
{
if(ll>rr)return inf;
if(ll>r||rr<l)return inf;
if(l<=ll&&r>=rr)return locmin[now];
int mid=(ll+rr)>>1;
return min(querylocmin(l,r,ll,mid,ls),querylocmin(l,r,mid+1,rr,rs));
}
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
int n,m;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",seq+i);
loc[seq[i]]=i;
}
build(1,n,1);
scanf("%d",&m);
while(m--){
int l,r,_seqmax,_seqmin,ansl=0,ansr=0;
scanf("%d %d",&l,&r);
bool flag=0;
while(l!=ansl||r!=ansr){
if(flag)l=ansl,r=ansr;
_seqmax=queryseqmax(l,r,1,n,1);
_seqmin=queryseqmin(l,r,1,n,1);
ansl=querylocmin(_seqmin,_seqmax,1,n,1);
ansr=querylocmax(_seqmin,_seqmax,1,n,1);
flag=1;
}
}
return 0;
}