bzoj2096 pilots
2016-07-18 17:32
204 查看
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
Sample Output
4
(有两个子串的长度为4: 5, 8, 6, 6 和8, 6, 6, 9.最长子串的长度就是4)
题解:
判断区间内的每一对值之差<
例如:
3 4 5 1 4 6
i到达5时,两个队列为:
q1[]={5}的下标(里面应该是5的下标,方便看)
q2[]={3 4 5}的下标
ans=3(i)-1(t)+1=3;
这时再进一个1
那么
q1[]={5 1}的下标
q2[]={1}的下标
队首大于3
执行while(),q1[]={1}的下标,直到不大于k,这时t=1的下标
q1[]={1}
q2[]={1}
那么ans=max(3,4-4+1)=3;
加入4,
q1[]={4};
q2[]={1 4};
ans=max(3,2)=3
加入6
q1[]={6}
q2[]={1 4 6}
6-1>k
while(),6-3<=k
ans=max(3,6(i)-5(t)+1)=3;
因此,最终连续的是,3 4 5最长。
因此,最难想的是如何去定义这个区间的左右端点,一旦q1首-q2首>k的时候,要把这两个值分开,因此找最小的下一个为新区间的左端点。至于为什么不改变右端点,因为此刻能到达的右端点就是最长区间了,如果要往左移动,只会使区间变得更短。
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
Sample Output
4
(有两个子串的长度为4: 5, 8, 6, 6 和8, 6, 6, 9.最长子串的长度就是4)
题解:
判断区间内的每一对值之差<
k,则相当于区间的最大值最小值之差
<k。很快的能想到,维护一个单调递增序列q1[]和一个单调递减序列q2[],定义这个区间的最大最小值,如果>k,则找队列中的下一个,相减与k作比较。个人认为最复杂的是区间的范围。代码中t是区间左端点,开始t=1,因此从第一个数开始。维护一个单调递减序列,一个递增,当两个队首差>k。那么在此之前区间最大最小之差<=k的情况区间从t=1到当前位置长度已经到达最大值。此时,只能去改变左端点,左端点要改变到哪里呢?肯定是两个队首对应的位置较小的一个的下一个,从这里算作新区间的左端点。
例如:
3 4 5 1 4 6
i到达5时,两个队列为:
q1[]={5}的下标(里面应该是5的下标,方便看)
q2[]={3 4 5}的下标
ans=3(i)-1(t)+1=3;
这时再进一个1
那么
q1[]={5 1}的下标
q2[]={1}的下标
队首大于3
执行while(),q1[]={1}的下标,直到不大于k,这时t=1的下标
q1[]={1}
q2[]={1}
那么ans=max(3,4-4+1)=3;
加入4,
q1[]={4};
q2[]={1 4};
ans=max(3,2)=3
加入6
q1[]={6}
q2[]={1 4 6}
6-1>k
while(),6-3<=k
ans=max(3,6(i)-5(t)+1)=3;
因此,最终连续的是,3 4 5最长。
因此,最难想的是如何去定义这个区间的左右端点,一旦q1首-q2首>k的时候,要把这两个值分开,因此找最小的下一个为新区间的左端点。至于为什么不改变右端点,因为此刻能到达的右端点就是最长区间了,如果要往左移动,只会使区间变得更短。
#include<iostream> #include<cstdio> using namespace std; int ans=1,k,n,a[1000005],q1[1000005],q2[1000005]; void work() { int l1=1,l2=1,r1=0,r2=0,t=1;//一开始没有赋值,导致错误 for(int i=1;i<=n;i++) { while(l1<=r1 && a[i]>=a[q1[r1]]) r1--;//维护一个单调递减的序列 while(l2<=r2 && a[i]<=a[q2[r2]]) r2--;//维护一个单调递增的序列 q1[++r1]=i;q2[++r2]=i; while(a[q1[l1]]-a[q2[l2]]>k) { if(q1[l1]<q2[l2]) t=q1[l1]+1,l1++; else t=q2[l2]+1,l2++; } //t是什么?用来记录子串的开头下标。看q1[l1]和q2[l2]的最小值,然后把最小值+1; ans=max(ans,i-t+1); //只要加入一个数,都会计算ans,一开始理解成了上一步的while运算之后才计算ans. } } int main() { cin>>k>>n; for(int i=1;i<=n;i++) cin>>a[i]; work(); cout<<ans<<endl; }
相关文章推荐
- angularjs/ionic $resource 出现 preflight的解决方案
- UMLOG: (ERROR) Umeng event's keys and values must be string ,key's max length 128 and value's max le
- zentao(禅道)迁移
- 新手入门贴:史上最全Web端即时通讯技术原理详解
- I00031 Look-and-say sequence
- 基于Hadoop生态圈的数据仓库实践 —— 进阶技术(四)
- python练习
- 网络性能测试工具iperf详细使用图文教程【转载】
- AFN之HTTPS
- 链接 skyeye-1.3.5 的时候出现 /usr/bin/ld: cannot find -lltdl
- Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xm
- 索引关键字的选取原则
- 索引关键字的选取原则
- 索引关键字的选取原则
- 索引关键字的选取原则
- 索引关键字的选取原则
- 索引关键字的选取原则
- 索引关键字的选取原则
- 索引关键字的选取原则
- 索引关键字的选取原则