UVa 11235 Frequent values

傳送門:UVa 11235

題目描述:給一個非降序排列的整數數組,對於一系列詢問[L,R],回答在此區間中出現次數最多的值出現的次數。

數組是非降序排列,因此相同的元素會排在一起,用value[]和cont[]記錄不同的元素及出現的次數,然後用num[],Left[]和Right[]數組維護第i位的元素出現在哪一段內以及這個元素在最左邊的位置和最右邊的位置。利用RMQ維護cont,記錄最大值。

當進行查詢時,首先判斷L和R是否在同一段內,如果是,則答案爲R-L+1;否則需要選擇Right[L]-L+1,RMQ(num[L]+1,num[R]-1)和R-Left[R]+1三段的最大值。

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=100050;
int c[maxn];
int value[maxn],cont[maxn];
int Left[maxn],Right[maxn],num[maxn];
int d[maxn][1005];
int RMQ_init(int n)
{
    for(int i=1;i<=n;i++) d[i][0]=cont[i];
    for(int j=1;(1<<j)<=n;j++)
        for(int i=1;i+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 n,Q;
    while(cin>>n)
    {
        if(n==0) break;
        cin>>Q;
        for(int i=1;i<=n;i++)
            scanf("%d",&c[i]);
        memset(Left,0,sizeof Left);
        memset(Right,0,sizeof Right);
        int t=0,tmp=c[1];
        value[++t]=c[1];cont[t]=1;
        num[1]=1;Left[1]=1;
        for(int i=2;i<=n;i++)
        {
            if(tmp==c[i])
            {
                cont[t]++;
                num[i]=t;
                Left[i]=Left[i-1];
            }
            else
            {
                Right[i-1]=i-1;
                tmp=c[i];value[++t]=c[i];
                cont[t]=1;
                num[i]=t;
                Left[i]=i;
            }
        }
        Right[n]=n;
        for(int i=n-1;i>=1;i--)
        {
            if(Right[i]==0)
            {
                Right[i]=Right[i+1];
            }
        }
        RMQ_init(t);
        while(Q--)
        {
            int L,R;
            scanf("%d %d",&L,&R);
            if(num[L]==num[R]) printf("%d\n",R-L+1);
            else
            {
                int tmp1=Right[L]-L+1;
                int tmp2=RMQ(num[L]+1,num[R]-1);
                int tmp3=R-Left[R]+1;
                printf("%d\n",max(max(tmp1,tmp2),tmp3));
            }
        }
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章