链接:https://ac.nowcoder.com/acm/contest/317/G
来源:牛客网
小a有一个长度为nn的排列。定义一段区间是"萌"的,当且仅当把区间中各个数排序后相邻元素的差为11
现在他想知道包含数x,yx,y的长度最小的"萌"区间的左右端点
也就是说,我们需要找到长度最小的区间[l,r][l,r],满足区间[l,r][l,r]是"萌"的,且同时包含数xx和数yy
如果有多个合法的区间,输出左端点最靠左的方案。
输入描述:
第一行三个整数N,x,yN,x,y,分别表示序列长度,询问的两个数 第二行有nn个整数表示序列内的元素,保证输入为一个排列
输出描述:
输出两个整数,表示长度最小"萌"区间的左右端点
示例1
输入
复制
5 2 3 5 2 1 3 4
输出
复制
2 4
说明
区间[2,4]={2,1,3}[2,4]={2,1,3}包含了2,32,3且为“萌”区间,可以证明没有比这更优的方案
示例2
输入
复制
8 3 5 6 7 1 8 5 2 4 3
输出
复制
5 8
备注:
保证2⩽n⩽105,1⩽x,y⩽n
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+5;
int a[maxn];
int b[maxn];
int c[maxn];
int l,r;
int main ( )
{
int n,x,y;
scanf("%d%d%d",&n,&x,&y);
for (int i=0; i<n; i++ )
{
scanf("%d",&a[i]);
c[a[i]]=i;
if(a[i]==x)l=i;
if(a[i]==y)r=i;
}
if(l>r)swap(l,r);
int mina=0x7fffffff;
int maxa=-1;
while(true)
{
for (int i=l; i<=r; i++ )
{
mina=min(mina,a[i]);
maxa=max(maxa,a[i]);
}
if(maxa-mina==r-l)
{
cout<<l+1<<" "<<r+1<<endl;
return 0;
}
for (int i=mina; i<=maxa; i++ )
{
if(c[i]<l)l=c[i];
else if(c[i]>r)r=c[i];
}
}
return 0;
}
下面是自己(rmq做的)的提交显示爆内存(不是很明白,网大佬指导)
#include<iostream>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
int lll,rrr;
int n,xx,yy,x,y;
const int MAXN=100010;
int dmax[MAXN][20];
int dmin[MAXN][20];
int d[MAXN];
struct Node
{
int l;
int r;
Node(int l,int r):r(r),l(l){}
};
void initMax(int n,int d[])
{
for(int i=1;i<=n;i++)dmax[i][0]=d[i];
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
dmax[i][j]=max(dmax[i][j-1],dmax[i+(1<<(j-1))][j-1]);
}
int getMax(int L,int R)
{
int k=0;
while((1<<(k+1))<=R-L+1)k++;
return max( dmax[L][k],dmax[R-(1<<k)+1][k] );
}
void initMin(int n,int d[])
{
for(int i=1;i<=n;i++)dmin[i][0]=d[i];
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
dmin[i][j]=min( dmin[i][j-1],dmin[i+(1<<(j-1))][j-1] );
}
int getMin(int L,int R)
{
int k=0;
while((1<<(k+1))<=R-L+1)k++;
return min( dmin[L][k],dmin[R-(1<<k)+1][k] );
}
int BFS()
{
queue<Node> Q;
while(!Q.empty()) Q.pop();
Q.push(Node(x,y));
while(!Q.empty())
{
Node node=Q.front();Q.pop();
int r=node.l,c=node.r;
int minn=getMin(r,c);
int maxx=getMax(r,c);
if((maxx-minn)==(c-r))
{
lll=r;
rrr=c;
return 1;
}
else
{
if(r-1>=1)
Q.push(Node(r-1,c));
if(c+1<=n)
Q.push(Node(r,c+1));
if(r-1>=1&&c+1<=n)
Q.push(Node(r-1,c+1));
}
}
return 0;
}
int main()
{
//cin>>n>>xx>>yy;
scanf("%d%d%d",&n,&xx,&yy);
for(int i=1;i<=n;i++)
{
//cin>>d[i];
scanf("%d",&d[i]);
if(d[i]==xx)x=i;
if(d[i]==yy)y=i;
}
if(x>y)swap(x,y);
//cout<<x<<" "<<y<<endl;
initMax(n,d);
initMin(n,d);
//cout<<getMin(x,y)<<getMax(x,y);
if(BFS()==1)
{
//cout<<lll<<" "<<rrr<<endl;
printf("%d %d\n",lll,rrr);
}
else
{
printf("0\n");
}
}