• Codeforces Round #333 (Div. 2) B. Approximating a Constant Range


    B. Approximating a Constant Range

    Time Limit: 20 Sec

    Memory Limit: 256 MB

    题目连接

    http://codeforces.com/contest/602/problem/B

    Description

    When Xellos was doing a practice course in university, he once had to measure the intensity of an effect that slowly approached equilibrium. A good way to determine the equilibrium intensity would be choosing a sufficiently large number of consecutive data points that seems as constant as possible and taking their average. Of course, with the usual sizes of data, it's nothing challenging — but why not make a similar programming contest problem while we're at it?

    You're given a sequence of n data points a1, ..., an. There aren't any big jumps between consecutive data points — for each 1 ≤ i < n, it's guaranteed that |ai + 1 - ai| ≤ 1.

    A range [l, r] of data points is said to be almost constant if the difference between the largest and the smallest value in that range is at most 1. Formally, let M be the maximum and m the minimum value of ai for l ≤ i ≤ r; the range [l, r] is almost constant if M - m ≤ 1.

    Find the length of the longest almost constant range.

    Input

    The first line of the input contains a single integer n (2 ≤ n ≤ 100 000) — the number of data points.

    The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 100 000).

    Output

    Print a single number — the maximum length of an almost constant range of the given sequence.

    Sample Input

    5
    1 2 3 3 2

    Sample Output

    4

    HINT

    题意

    给你n个数,要求你找到最长的区间,使得这个区间的最大值减去最小值之差的绝对值小于等于1

    题解:

    我是先做到它的升级版:此题升级版

    我大概讲一下吧:

    不难发现:如果(l,r),那么(l+1,r)必然也合法。

    所以我们枚举左端点,右端点是不断递增的,所以是线性的。

    可以用ST表做,也可以用优先队列做。

    优先队列代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 100050
     4 int n,val[N],flag[N];
     5 struct Node
     6 {
     7   int id,val;
     8   bool operator <(const Node&b)const
     9   {return val<b.val;}
    10 };
    11 template<typename T>void read(T&x)
    12 {
    13   int k=0; char c=getchar();
    14   x=0;
    15   while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
    16   if (c==EOF)exit(0);
    17   while(isdigit(c))x=x*10+c-'0',c=getchar();
    18   x=k?-x:x;
    19 }
    20 int main()
    21 {
    22   #ifndef ONLINE_JUDGE
    23   freopen("aa.in","r",stdin);
    24   #endif
    25   read(n);
    26   for(int i=1;i<=n;i++)read(val[i]);
    27   int r=0,ans=0;
    28   priority_queue<Node>mx,mi;
    29   for(int i=1;i<=n;i++)
    30     {
    31       while(r+1<=n&&(mi.empty()||
    32              (fabs(val[r+1]-mx.top().val)<=1&&fabs(val[r+1]+mi.top().val)<=1)))
    33     {
    34       mx.push(Node{r+1,val[r+1]});
    35       mi.push(Node{r+1,-val[r+1]});
    36       r++;
    37     }
    38       ans=max(ans,r-i+1);
    39       flag[i]=1;
    40       while(!mi.empty()&&flag[mi.top().id])mi.pop();
    41       while(!mx.empty()&&flag[mx.top().id])mx.pop();
    42     }
    43   printf("%d
    ",ans);
    44 }
    View Code

    ST表代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 100050
     4 int n,val[N];
     5 int mm[N],mi[N][20],mx[N][20];
     6 template<typename T>void read(T&x)
     7 {
     8   int k=0; char c=getchar();
     9   x=0;
    10   while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
    11   if (c==EOF)exit(0);
    12   while(isdigit(c))x=x*10+c-'0',c=getchar();
    13   x=k?-x:x;
    14 }
    15 void init_ST(int n)
    16   {
    17     mm[0]=-1;
    18     for(int i=1;i<=n;i++)
    19       {
    20     mm[i]=(i&(i-1))==0?mm[i-1]+1:mm[i-1];
    21     mx[i][0]=mi[i][0]=val[i];
    22       }
    23     for(int i=1;i<=20;i++)
    24       for(int j=1;j+(1<<i)-1<=n;j++)
    25     {
    26       mi[j][i]=min(mi[j][i-1],mi[j+(1<<(i-1))][i-1]);
    27       mx[j][i]=max(mx[j][i-1],mx[j+(1<<(i-1))][i-1]);
    28     }
    29   }
    30 int rmq(int x,int y)
    31   {
    32     int k=mm[y-x+1];
    33     int ans=max(mx[x][k],mx[y-(1<<k)+1][k]);
    34     ans-=min(mi[x][k],mi[y-(1<<k)+1][k]);
    35     return ans;
    36   }
    37 int main()
    38 {
    39   #ifndef ONLINE_JUDGE
    40   freopen("aa.in","r",stdin);
    41   #endif
    42   read(n);
    43   for(int i=1;i<=n;i++)read(val[i]);
    44   init_ST(n);
    45   int r=0,ans=0;
    46   for(int i=1;i<=n;i++)
    47     {
    48       while(r+1<=n&&rmq(i,r+1)<=1)r++;
    49       ans=max(ans,r-i+1);
    50     }
    51   printf("%d
    ",ans);
    52 }
    View Code
  • 相关阅读:
    java中的Class类
    装机
    CSS入门
    初级HTML
    IO加强
    Lambda表达式
    IOStream-基础
    JavaSE阶段基础内容(不包括I/O,常用类,集合)
    markdown学习
    Log4j配置详解
  • 原文地址:https://www.cnblogs.com/mmmqqdd/p/10827794.html
Copyright © 2020-2023  润新知