UVA - 11235 Frequent values 频繁出现的数值 RMQ+游程编码

题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=23846

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI 3.1415926535897932384626
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n)  for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n)  for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n)  for(int i=(n) ;i>=0 ;i--)
#define  lson   num<<1,le,mid
#define rson    num<<1|1,mid+1,ri
#define MID   int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk    make_pair
#define _f     first
#define _s     second

using namespace std;
//const int INF=    ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxn= 100000+20   ;
//const int maxm=    ;
//by yskysker123

int n,m;           //元素个数,询问个数
int d[maxn][40];  //RMQ[起点][长度为2^k]
int le[maxn],ri[maxn];   //le[x]:第x段对应的 起点位置,ri[x]:第x段对应的终点位置。
int a[maxn],num[maxn];  //a[i]存储第i个位置的数大小,num[i]:第x个元素对应段的序号。
int val[maxn],countt[maxn];//val[x],countt[x]:第x段表示的元素值,第x段的元素个数。
int N;                //总段数。
void RMQ_init()
{
    for(int i=1;i<=N;i++)
      d[i][0] = countt[i];

   /*    RMQ的顺序不是这样的。
    for(int i=1;i  <=N;i++)
    {
        for(int j=1;i+(1<<j)-1 <=N ;j++  )
        {
            d[i][j]=max(d[i][j-1],d[i+ 1<<(j-1)  ][j-1]); 因为状态转移方程里面有个 j-1(有个 '-'),所以
        }                                                 最外一层循环应该是j。
    }
    */
    for(int j=1;(1<<j) <=N ;j++)
    {
        for(int i=1;i+ (1<<j)-1 <=N ;i++ )
        {
            d[i][j]=max(d[i][j-1],d[i+(1<<(j-1) ) ][j-1] );
        }
    }



}

int RMQ(int L,int R)
{
    if(L>R)  return 0;
    int k=0;
    while( (1<<(k+1) )<=R-L+1 )  k++;
    return   max( d[L][k]  ,d[R-(1<<k )+1 ][k]  );
}


int main()
{
    int x;
    while(~scanf("%d",&n)&&n)
    {
        scanf("%d",&m);
        memset(countt,0,sizeof countt);
        int p=1,pre=-INF;
        int cnt=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            x=a[i];
            if(x!=pre)  cnt++,pre=x,p=i,val[cnt]=x;

            num[i]=cnt;
            le[cnt]=p;
            countt[cnt]++;
        }
        p=n,pre=INF;
        N=cnt;  //N表示段数。
        cnt++;
        for(int i=n;i>=1;i--)
        {
            x=a[i];
            if(x!=pre)  cnt--,pre=x,p=i;

             ri[cnt]=p;
        }

        RMQ_init();
        int ans=0,LE,RI;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&LE,&RI);
            int p1=num[LE];
            int x=     ri[p1]-LE+1;

            int p2=num[RI];
            int y=     RI-le[p2]+1;

            if(p1==p2)  ans= RI-LE+1;
            else
            {
                ans=max(x,  y);
                ans=max(ans,RMQ(p1+1,p2-1  ) );
            }

            printf("%d\n",ans);
        }

    }


    return 0;
}

    原文作者:游程编码问题
    原文地址: https://blog.csdn.net/yskyskyer123/article/details/48786193
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞