首页 > 代码库 > 2096: [Poi2010]Pilots单调队列题解
2096: [Poi2010]Pilots单调队列题解
Description
Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值。耍畸形一个人是不行的,于是他找到了你。
Input
输入:第一行两个有空格隔开的整数k(0<=k<=2000,000,000),n(1<=n<=3000,000),k代表Tz设定的最大值,n代表难度序列的长度。第二行为n个由空格隔开的整数ai(1<=ai<=2000,000,000),表示难度序列。
Output
输出:最大的字串长度。
Sample Input
3 9
5 1 3 5 8 6 6 9 10
5 1 3 5 8 6 6 9 10
Sample Output
4
(有两个子串的长度为4: 5, 8, 6, 6 和8, 6, 6, 9.最长子串的长度就是4)
(有两个子串的长度为4: 5, 8, 6, 6 和8, 6, 6, 9.最长子串的长度就是4)
题解:这个就是单调队列的裸题啦,不过需要我们同时维护一个最大和一个最小的队列,唔,单调队列我就不细讲了,不过这道题具体实现的时候我出了一点的问题所以具体怎么写还是看注释吧:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> using namespace std; long long tot,k,n,f1[3000010],f2[3000010]; long long t1,t2,head1,head2,ans,a[3000010]; int main() { scanf("%d %d",&k,&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); t1=t2=0; head1=head2=1; ans=1; for (int i=1;i<=n;i++) { while ((a[i]>a[f1[t1]])&&(t1>=head1)) t1-=1;//维护最大值 while ((a[i]<a[f2[t2]])&&(t2>=head2)) t2-=1;//维护最小值 t1+=1; t2+=1; f1[t1]=i;//记录下当前这个值的位置 f2[t2]=i;//记录下当前这个值的位置 //我当时就卡在这个地方了,当初记录的是这个值本身,结果还是要记录值的位置,还因此开了四个数组,还卡在什么莫名的地方调不出来,真的是。。。。 while (a[f1[head1]]-a[f2[head2]]>k)如果当前最大最小之差已经不符合条件了,换区间 { if (f1[head1]<f2[head2]) head1+=1,tot=f1[head1-1]; else head2+=1,tot=f2[head2-1]; } ans=max(i-tot,ans); } printf("%d",ans); return 0; }
2096: [Poi2010]Pilots单调队列题解
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。