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
",i,j,d[i][j]);
       }

   }
      // printf("
");
   }

}
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
",Left[i],Right[i]);
      }
      printf("
");
      */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
",(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
",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
",Left[i],Right[i]);
      }
      printf("
");
      */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
",(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
",answer);
          }

      }

   }
    return 0;
}
原文地址:https://www.cnblogs.com/xianbin7/p/4530859.html