sdut 1452 选美大赛 单调队列

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1452

题目:中文.....

思路:

单调队列维护最大最小,st记录起始位置,如果出现st到i的最大最小差值大于k,要么移动最大要么移动最小,我们只要移动那个坐标小的即可。

//#pragma comment(linker,"/STACK:327680000,327680000")  

#include <iostream>  

#include <cstdio>  

#include <cmath>  

#include <vector>  

#include <cstring>  

#include <algorithm>  

#include <string>  

#include <set>  

#include <functional>  

#include <numeric>  

#include <sstream>  

#include <stack>  

#include <map>  

#include <queue>  

  

#define CL(arr, val)    memset(arr, val, sizeof(arr))  

  

#define ll long long  

#define inf 0x7f7f7f7f  

#define lc l,m,rt<<1  

#define rc m + 1,r,rt<<1|1  

#define pi acos(-1.0)  

#define ll long long  

#define L(x)    (x) << 1  

#define R(x)    (x) << 1 | 1  

#define MID(l, r)   (l + r) >> 1  

#define Min(x, y)   (x) < (y) ? (x) : (y)  

#define Max(x, y)   (x) < (y) ? (y) : (x)  

#define E(x)        (1 << (x))  

#define iabs(x)     (x) < 0 ? -(x) : (x)  

#define OUT(x)  printf("%I64d\n", x)  

#define lowbit(x)   (x)&(-x)  

#define Read()  freopen("din.txt", "r", stdin)  

#define Write() freopen("dout.txt", "w", stdout);  

  

  

#define N 100007  

using namespace std;  

  

int a[N];  

int qmin[N*10],qmax[N*10];  

int ifr,itl,afr,atl;  

  

struct node  

{  

    int u,v;  

}g[N];  

int len,num;  

  

int n,k;  

  

int main()  

{  

    //Read();  

    int i;  

    while (~scanf("%d%d",&n,&k))  

    {  

        for (i = 1; i <= n; ++i) scanf("%d",&a[i]);  

  

        int len = 0;  

        ifr = afr = 0;  

        itl = atl = -1;  

        int st = 1;  

        CL(qmin,0);  

        CL(qmax,0); len = 0; num = 0;  

  

        for (i = 1; i <= n; ++i)  

        {  

            //最小

            while (ifr <= itl && a[qmin[itl]] > a[i]) itl--;  

            qmin[++itl] = i;  

            //最大

            while (afr <= atl && a[qmax[atl]] < a[i]) atl--;  

            qmax[++atl] = i;  

  

            //处理差值大于k的情况

            while (ifr <= itl && afr <= atl && a[qmax[afr]] - a[qmin[ifr]] > k)  

            {  

                //移动坐标小的那个

                if (qmax[afr] < qmin[ifr])  

                {  

                    st = qmax[afr] + 1;  

                    afr++;  

                }  

                else  

                {  

                    st = qmin[ifr] + 1;  

                    ifr++;  

                }  

            }  

            if (len < i - st + 1)  

            {  

                len = i - st + 1;  

                num = 0;  

                g[num].u = st;  

                g[num].v = i;  

                num++;  

            }  //记录最大

            else if (len == i - st + 1)  

            {  

                g[num].u = st;  

                g[num].v = i;  

                num++;  

            }  

        }  

        printf("%d %d\n",len,num);  

        for (i = 0; i < num; ++i)  

        printf("%d %d\n",g[i].u,g[i].v);  

  

  

    }  

    return 0;  

}  

   

  

 

你可能感兴趣的:(队列)