Fork me on GitHub

UVA 11235 Frequent Values ---RMQ

大白书上的例题,具体讲解见大白书,最好用用一个Log数组直接求k,这样就是纯O(1)了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 100003

int a[N],num[N],le[N],ri[N],cnt[N];
int d[N][21],n,type;


void RMQ_init()
{
    int i,j;
    for(i=1;i<=type;i++)
        d[i][0] = cnt[i];
    for(j=1;(1<<j)<=type;j++)
    {
        for(i=1;i+(1<<j)-1<=type;i++)
            d[i][j] = max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
    }
}

int LOG[50007];
void getLog(int n)
{
    for(int i=0;i<=n;i++)
        LOG[i] = (int)(log((double)i)/log(2.0));
}

int RMQ(int l,int r)
{
    int k = LOG[R-L+1];
    return max(d[l][k],d[r-(1<<k)+1][k]);
}

int main()
{
    int q,i,j,pos;
    int l,r;
    while(scanf("%d",&n)!=EOF && n)
    {
        scanf("%d",&q);
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        a[0] = -1000000;
        type = 0;
        for(pos=1;pos<=n;pos++)
        {
            if(a[pos] != a[pos-1])
            {
                if(pos != 1 )
                    cnt[type] = pos-le[pos-1];
                num[pos] = ++type;
                for(j=le[pos-1];j<=pos-1;j++)
                    ri[j] = pos-1;
                le[pos] = pos;
                if(pos == n)
                    cnt[type] = 1,ri[pos] = pos;
            }
            else
            {
                le[pos] = le[pos-1];
                num[pos] = num[pos-1];
                if(pos == n)
                {
                     cnt[type] = pos - le[pos] + 1;
                     for(j=le[pos];j<=n;j++)
                        ri[j] = n;
                }
            }
        }
        RMQ_init();
        while(q--)
        {
            scanf("%d%d",&l,&r);
            if(num[l] == num[r])
            {
                printf("%d\n",r-l+1);
                continue;
            }
            int lmax = ri[l]-l+1;
            int rmax = r-le[r]+1;
            int mmax;
            if(num[l]+1 > num[r]-1)
                mmax = 0;
            else
                mmax = RMQ(num[l]+1,num[r]-1);
            printf("%d\n",max(mmax,max(lmax,rmax)));
        }
    }
    return 0;
}
View Code

 

 

posted @ 2014-03-04 12:36  whatbeg  阅读(261)  评论(0)    收藏  举报