uva 11235

2007/2008 ACM International Collegiate Programming Contest University of Ulm Local Contest

 

Problem F: Frequent values

You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given several queries consisting of indices i and j (1 ≤ i ≤ j ≤ n). For each query, determine the most frequent value among the integers ai , ... , aj.

Input Specification

The input consists of several test cases. Each test case starts with a line containing two integers n and q (1 ≤ n, q ≤ 100000). The next line contains n integers a1 , ... , an (-100000 ≤ ai ≤ 100000, for each i ∈ {1, ..., n}) separated by spaces. You can assume that for each i ∈ {1, ..., n-1}: ai ≤ ai+1. The following q lines contain one query each, consisting of two integers i and j (1 ≤ i ≤ j ≤ n), which indicate the boundary indices for the query.

The last test case is followed by a line containing a single 0.

Output Specification

For each query, print one line with one integer: The number of occurrences of the most frequent value within the given range.

Sample Input

10 3

-1 -1 1 1 1 1 3 10 10 10

2 3

1 10

5 10

0

Sample Output

1

4

3
题目描述:求某段给定区间内出现最多的数出现的次数,这个序列数不下降的
由于不下降,所有相等的数会聚集在一起,采用游程编码,
(a,b)表示有b个连续的a.
由于不改变某个点的值,可以采用RMQ或者线段树进行统计.
体会到递推最重要的就是递推顺序和初始化。
#include <iostream>

#include <stdio.h>

#include <string.h>

#include <algorithm>

#define maxn 100100

#define LL long long

using namespace std;



int value[maxn];

int count_[maxn];

int num[maxn];

int Left[maxn];

int Right[maxn];

int a[maxn];

LL MAXN[maxn*4];

LL d[maxn][30];

int n,q;

int ql,qr;

/*int op,ql,qr,p,v;

void update(int o,int L,int R)

{

   int M=L+(R-L)/2;

   if(L==R)

    MAXN[o]=v;

    else

    {

          if(p<=M)

        update(o*2,L,M);

            else

        update(o*2+1,M+1,R);

       MAXN[o]=max(MAXN[o*2],MAXN[o*2+1]);

    }

}

LL query(int o,int L,int R)

{

   int M=L+(R-L)/2;

   LL ans=-1000;

   if(ql<=L && R<=qr)

   return MAXN[o];



      if(ql<=M)

         ans=max(ans,query(o*2,L,M));

      if(M<qr)

        ans=max(ans,query(o*2+1,M+1,R));

        return  ans;



}*/

void init()

{

    memset(count_,0,sizeof(count_));

    memset(MAXN,0,sizeof(MAXN));

}

LL Max(LL a,LL b)

{

    if(a>=b)

        return a;

    else

        return b;

}

void RMQ_init(int t)

{

  //for(int i=1;i<=n;i++)

    //d[i][0]=b[i];

   for(int j=1;(1<<j)<=t;j++)

   {

        for(int i=1;i<=t;i++)

   {

      if( (i+(1<<j)-1) <=t )

       {

           d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);

           //printf("%d %d %lld\n",i,j,d[i][j]);

       }



   }

      // printf("\n");

   }



}

LL  RMQ(int L,int R,int t)

{

   int k=0;

   while((1<<k+1)<= (R-L)+1 )  k++;

   return max(d[L][k],d[R-(1<<k)+1][k]);

}



int main()

{

   while(~scanf("%d",&n) && n!=0)

   {

       scanf("%d",&q);

       init();

      int  t=0;

       a[0]=maxn;

      for(int i=1;i<=n;i++)

      {

         scanf("%d",&a[i]);

         if(a[i]==a[i-1])

         {

             count_[t]++;

             num[i]=t;

         }

         else

         {

             if(t!=0)

             {

               for(int k=i-count_[t];k<=i-1;k++)

             {

                 Left[k]=(i-count_[t]);

                 Right[k]=i-1;

             }

             }



             value[++t]=a[i];

             ++count_[t];

             num[i]=t;

         }

      }

      for(int k=n-count_[t]+1;k<=n;k++)

             {

                 Left[k]=(n-count_[t]+1);

                 Right[k]=n;

             }

        for(int i=1;i<=t;i++)

        {

          //  cout<<count_[i]<<" ";

           // p=i;

            //v=count_[i];

           // update(1,1,t);

            d[i][0]=count_[i];

        }

        RMQ_init(t);

     // for(int i=1;i<=7;i++)

         // printf("%d ",MAXN[i]);

     /* for(int i=1;i<=n;i++)

      {

          printf("%d %d\n",Left[i],Right[i]);

      }

      printf("\n");

      */int LLL,RRR;

      for(int j=1;j<=q;j++)

      {

          LL answer=0;

          scanf("%d%d",&LLL,&RRR);

          if(Right[LLL]==Right[RRR] && Left[LLL]==Left[RRR])

            printf("%d\n",(RRR-LLL)+1);

          else

          {

              answer=Max(answer,Right[LLL]-LLL+1);

          answer=Max(answer,RRR-Left[RRR]+1);

          ql=num[LLL]+1;qr=num[RRR]-1;

         /* cout<<Right[LLL]-LLL+1<<endl;

         cout<<RRR-Left[RRR]+1<<endl;

         cout<<ql<<endl;

         cout<<qr<<endl;



          */if(ql<=qr)

          answer=Max(answer,RMQ(ql,qr,t));

          //cout<<query(1,1,t)<<endl;

            printf("%lld\n",answer);

          }



      }



   }

    return 0;

}
#include <iostream>

#include <stdio.h>

#include <string.h>

#include <algorithm>

#define maxn 100100

#define LL long long

using namespace std;



int value[maxn];

int count_[maxn];

int num[maxn];

int Left[maxn];

int Right[maxn];

int a[maxn];

LL MAXN[maxn*4];

int n,q;



int op,ql,qr,p,v;

void update(int o,int L,int R)

{

   int M=L+(R-L)/2;

   if(L==R)

    MAXN[o]=v;

    else

    {

          if(p<=M)

        update(o*2,L,M);

            else

        update(o*2+1,M+1,R);

       MAXN[o]=max(MAXN[o*2],MAXN[o*2+1]);

    }

}

LL query(int o,int L,int R)

{

   int M=L+(R-L)/2;

   LL ans=-1000;

   if(ql<=L && R<=qr)

   return MAXN[o];



      if(ql<=M)

         ans=max(ans,query(o*2,L,M));

      if(M<qr)

        ans=max(ans,query(o*2+1,M+1,R));

        return  ans;



}

void init()

{

    memset(count_,0,sizeof(count_));

    memset(MAXN,0,sizeof(MAXN));

}

LL Max(LL a,LL b)

{

    if(a>=b)

        return a;

    else

        return b;

}

int main()

{

   while(~scanf("%d",&n) && n!=0)

   {

       scanf("%d",&q);

       init();

       int t=0;

       a[0]=maxn;

      for(int i=1;i<=n;i++)

      {

         scanf("%d",&a[i]);

         if(a[i]==a[i-1])

         {

             count_[t]++;

             num[i]=t;

         }

         else

         {

             if(t!=0)

             {

               for(int k=i-count_[t];k<=i-1;k++)

             {

                 Left[k]=(i-count_[t]);

                 Right[k]=i-1;

             }

             }



             value[++t]=a[i];

             ++count_[t];

             num[i]=t;

         }

      }

      for(int k=n-count_[t]+1;k<=n;k++)

             {

                 Left[k]=(n-count_[t]+1);

                 Right[k]=n;

             }

        for(int i=1;i<=t;i++)

        {

          //  cout<<count_[i]<<" ";

            p=i;

            v=count_[i];

            update(1,1,t);

        }

     // for(int i=1;i<=7;i++)

         // printf("%d ",MAXN[i]);

     /* for(int i=1;i<=n;i++)

      {

          printf("%d %d\n",Left[i],Right[i]);

      }

      printf("\n");

      */int LLL,RRR;

      for(int j=1;j<=q;j++)

      {

          LL answer=0;

          scanf("%d%d",&LLL,&RRR);

          if(Right[LLL]==Right[RRR] && Left[LLL]==Left[RRR])

            printf("%d\n",(RRR-LLL)+1);

          else

          {

              answer=Max(answer,Right[LLL]-LLL+1);

          answer=Max(answer,RRR-Left[RRR]+1);

          ql=num[LLL]+1;qr=num[RRR]-1;

         /* cout<<Right[LLL]-LLL+1<<endl;

         cout<<RRR-Left[RRR]+1<<endl;

         cout<<ql<<endl;

         cout<<qr<<endl;



          */if(ql<=qr)

          answer=Max(answer,query(1,1,t));

          //cout<<query(1,1,t)<<endl;

            printf("%lld\n",answer);

          }



      }



   }

    return 0;

}

 

你可能感兴趣的:(uva)