hdu 3530 单调队列水题

来源:互联网 发布:淘宝刷手退款能报警 编辑:程序博客网 时间:2024/05/22 14:12


给你一个数列找到最长的子序列   中的最大值减最小值值m   k之间



建立两个单调队列   一个递增    一个递减    当两个队首满足情况是就进行比较 找到最大值  

当不满足是旧的移动队首      怎样移???

 移动队首id较小的一个   


#include<stdio.h>#include<string.h>#include<iostream>using namespace std;int max(int a,int b){    return a>b?a:b;}int abs(int a){    return a<0?-a:a;}int main(){    int n,m,k,i,j;    int num[100010];    int ma[100010],mi[100010];    int ida[100010],idi[100010];    while(~scanf("%d%d%d",&n,&m,&k))    {        for(i=1;i<=n;i++)        scanf("%d",&num[i]);        int fax=0,tax=0;        int fin=0,tin=0;        int tt=0;        int now=0;        for(i=1;i<=n;i++)        {            while(fax<tax&&ma[tax]<=num[i]) tax--;            ma[++tax]=num[i];            ida[tax]=i;            while(fin<tin&&mi[tin]>=num[i]) tin--;            mi[++tin]=num[i];            idi[tin]=i;            while(ma[fax+1]-mi[fin+1]>k&&fax<tax&&fin<tin)            {                if(ida[fax+1]<=idi[fin+1])                {                    fax++;                    now=ida[fax];                }                else                {                    fin++;                    now=idi[fin];                }            }            if(ma[fax+1]-mi[fin+1]>=m)            tt=max(tt,i-now);        }        printf("%d\n",tt);    }    return 0;}

0 0
原创粉丝点击