题目链接
题目大意
找到最长的字串使其满足最大元素和最小元素的差值大于等于mi小于等于ma
rmq+尺取
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define debug printf("I am here\n");
using namespace std;
typedef long long ll;
const int maxn=1e6+5,inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
int n,mi,ma,a[maxn],dpma[maxn][21],dpmi[maxn][21];
void rmq(){
for(int i=1;i<=n;i++){
dpma[i][0]=dpmi[i][0]=a[i];
}
for(int i=1;(1<<i)<=n;i++){
for(int j=1;j+(1<<i)-1<=n;j++){
dpma[j][i]=max(dpma[j][i-1],dpma[j+(1<<(i-1))][i-1]);
dpmi[j][i]=min(dpmi[j][i-1],dpmi[j+(1<<(i-1))][i-1]);
}
}
}
int querymax(int l,int r){
int k=log2(r-l+1);
return max(dpma[l][k],dpma[r+1-(1<<k)][k]);
}
int querymin(int l,int r){
int k=log2(r-l+1);
return min(dpmi[l][k],dpmi[r+1-(1<<k)][k]);
}
int main(){
while(scanf("%d%d%d",&n,&mi,&ma)!=-1){
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
rmq();
int l=1,r=1,ans=0;
while(r<=n){
while(querymax(l,r)-querymin(l,r)>ma){
l++;
}
if(querymax(l,r)-querymin(l,r)>=mi){
ans=max(ans,r-l+1);
}
r++;
}
printf("%d\n",ans);
}
return 0;
}
还可以固定左端点,二分右端点使得最大差值小于等于ma,然后在判断最大差值是否大于等于mi,如果满足条件则更新一次答案,否则舍去,因为无论再怎么舍去元素也无法使得最大差值大于mi了
这个TLE了和第一个复杂度应该一样,但是nlogn,但是常数大一点,应该被卡常了
rmq+二分
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define debug printf("I am here\n");
using namespace std;
typedef long long ll;
const int maxn=1e6+5,inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
int n,mi,ma,a[maxn],dpma[maxn][21],dpmi[maxn][21];
void rmq(){
for(int i=1;i<=n;i++){
dpma[i][0]=dpmi[i][0]=a[i];
}
for(int i=1;(1<<i)<=n;i++){
for(int j=1;j+(1<<i)-1<=n;j++){
dpma[j][i]=max(dpma[j][i-1],dpma[j+(1<<(i-1))][i-1]);
dpmi[j][i]=min(dpmi[j][i-1],dpmi[j+(1<<(i-1))][i-1]);
}
}
}
int querymax(int l,int r){
int k=log2(r-l+1);
return max(dpma[l][k],dpma[r+1-(1<<k)][k]);
}
int querymin(int l,int r){
int k=log2(r-l+1);
return min(dpmi[l][k],dpmi[r+1-(1<<k)][k]);
}
int main(){
while(scanf("%d%d%d",&n,&mi,&ma)!=-1){
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
rmq();
//没必要init
int ans=0;
for(int i=1;i<=n;i++){
int l=i,r=n,last;
while(r>=l){
int mid=(l+r)/2;
if(querymax(i,mid)-querymin(i,mid)>ma){
r=mid-1;
}else{
last=mid;
l=mid+1;
}
}
if(querymax(i,last)-querymin(i,last)>=mi){
ans=max(ans,last-i+1);
}
}
printf("%d\n",ans);
}
return 0;
}