社区讨论
提供一种极限卡过的方法(O(nlogn)做法)
P3512[POI 2010] PIL-Pilots参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @lobf2dqb
- 此快照首次捕获于
- 2023/10/29 19:57 2 年前
- 此快照最后确认于
- 2023/11/04 01:31 2 年前
方法:二分答案枚举区间长度,利用单调队列算出每个区间内的最大值和最小值,然后判断。
复杂度:枚举logn,计算最大最小值并判断n。
以下是代码
CPP#include <cstdio>
#include <cstring>
using namespace std;
int a[3000005];
int maxn[3000005],minn[3000005];
int q1[3000005],q2[3000005];
int main(){
int n,dis;
scanf("%d %d",&dis,&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int l=0,r=n,res=0;
while(l<=r){
int k=(l+r)/2;
int head1=1,tail1=1,head2=1,tail2=1;
q1[tail1]=q2[tail2]=1;
for(int i=2;i<=n;i++){
while(head1<=tail1 and i-q1[head1]>=k) head1++;
while(head2<=tail2 and i-q2[head2]>=k) head2++;
while(head1<=tail1 and a[q1[tail1]]<=a[i]) tail1--;
while(head2<=tail2 and a[q2[tail2]]>=a[i]) tail2--;
q1[++tail1]=i,q2[++tail2]=i;
maxn[i]=q1[head1],minn[i]=q2[head2];
}
bool flag=0;
for(int i=k;i<=n;i++)if(a[maxn[i]]-a[minn[i]]<=dis)flag=1;
if(flag){
res=k;
l=k+1;
}
else r=k-1;
}
printf("%d\n",res);
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...