UVA 11235 Frequent values

RMQ

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

const int INF=0x7FFFFFFF;
const int maxn=100000+10;
int a[maxn];
int Value[maxn],Count[maxn];
int num[maxn],left[maxn],right[maxn];
int N,Q,tot;
int Max[maxn][32];

void init()
{
    tot=0;
    a[0]=-INF;
    memset(Count,0,sizeof Count);
    a[N+1]=-INF;
    memset(num,-1,sizeof num);
    memset(left,-1,sizeof left);
    memset(right,-1,sizeof right);
}

void init_RMQ()
{
    memset(Max,0,sizeof Max);
    for(int i=1; i<=tot; i++) Max[i][0] = Count[i];
    for(int j=1; (1<<j)<=tot; j++)
    {
        for(int i=1; i+(1<<j)<=tot; i++)
        {
            Max[i][j] = max(Max[i][j-1], Max[i+(1<<(j-1))][j-1]);
        }
    }
}

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


int main()
{
    while(~scanf("%d",&N))
    {
        if(N==0) break;
        scanf("%d",&Q);
        init();
        for(int i=1; i<=N; i++) scanf("%d",&a[i]);
        for(int i=1; i<=N; i++)
        {
            if(a[i]!=a[i-1])
            {
                tot++;
                Value[tot]=a[i];
            }
            Count[tot]++;
        }

        init_RMQ();

        int id=0,P;
        for(int i=1; i<=N; i++)
        {
            if(num[i]==-1)
            {
                id++;
                for(int j=i; j<=N+1; j++)
                {
                    if(a[j]!=a[i])
                    {
                        P=j-1;
                        break;
                    }
                }
                for(int j=i; j<=P; j++)
                {
                    num[j]=id;
                    left[j]=i;
                    right[j]=P;
                }
            }
        }

        for(int i=1; i<=Q; i++)
        {
            int LL,RR;
            scanf("%d%d",&LL,&RR);
            if(num[LL]==num[RR]) printf("%d
",RR-LL+1);
            else
            {
                int ans;
                ans=max((right[LL]-LL+1),(RR-left[RR]+1));
                if(num[LL]+1<=num[RR]-1) ans=max(ans,(Query(num[LL]+1,num[RR]-1)));
                printf("%d
",ans);
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/4945719.html