zoukankan      html  css  js  c++  java
  • [POJ] 3368 / [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

    题解:因为序列a1,a2,a3...an是不下降的,所以相同的数字肯定连续集中在一段。维护d[i][0]为相同数字从左到右分别从1到n开始编号,例如样例中的d[i][0]从左到右为 1,2,1,2,3,4,1,1,2,3。这样就转化成了RMQ问题。因为没有中途修改a[i]的值,所以可以用Sparse-Table算法,d[i][j]表示从i开始长度为2^i的一段元素的最大值。维护数组Left[i],Right[i]分别为相同数字连续一段最左端的编号和最右端的编号,例如样例中的Left[i]分别为:1,1,3,3,3,3,7,8,8,8。所以,序列分布共有以下几种情况:

                  
         [1] ans=max(Right[i]-L+1,R-Left[j]+1)
         [2] ans=R-L+1

         [3] ans=max(max(Right[i]-L+1,R-Left[j]+1),RMQ(k))

    代码:
      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<math.h>
      4 #include<ctype.h>
      5 #include<stdlib.h>
      6 #include<stdbool.h>
      7 
      8 #define rep(i,a,b)      for(i=(a);i<=(b);i++)
      9 #define red(i,a,b)      for(i=(a);i>=(b);i--)
     10 #define clr(x,y)        memset(x,y,sizeof(x))
     11 #define sqr(x)          (x*x)
     12 #define LL              long long
     13 
     14 int i,j,n,m,maxn,q,
     15     a[100003],d[100003][50],Left[100003],Right[100003];
     16 
     17 void pre()
     18 {
     19     clr(d,0);
     20     clr(Left,0);
     21     clr(Right,0);
     22     clr(a,0);
     23 }
     24 
     25 int max(int a,int b)
     26 {
     27     if(a>b) return a;
     28     return b;
     29 }
     30 
     31 int RMQ_init()
     32 {
     33     int i,j;
     34      
     35     for(j=1;(1<<j)<=n;j++)
     36         for(i=1;i+(1<<j)-1<=n;i++)
     37         d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
     38     
     39     return 0;
     40         
     41 }
     42 
     43 int RMQ(int L,int R)
     44 {
     45     int k;
     46     k=0;
     47     
     48     while(1<<(k+1)<=R-L+1) k++;
     49  
     50     maxn=max(d[L][k],d[R-(1<<k)+1][k]);;
     51    
     52     return 0;
     53     
     54 }
     55 
     56 int Num_init()
     57 {
     58     int i;
     59 
     60     a[0]=35113;
     61     rep(i,1,n)
     62         if(a[i]!=a[i-1]) Left[i]=i;
     63         else Left[i]=Left[i-1];
     64   
     65     a[n+1]=35113;
     66     red(i,n,1)
     67         if(a[i]!=a[i+1]) Right[i]=i;
     68         else Right[i]=Right[i+1];
     69     
     70     
     71     return 0;
     72 }
     73 
     74 int main()
     75 {
     76     int i,x,y;
     77     
     78      while(true) {
     79          pre();    
     80          scanf("%d",&n); 
     81         
     82          if(n==0) exit(0);
     83          scanf("%d",&q);
     84          a[0]=35113;
     85          rep(i,1,n) {
     86             scanf("%d",&a[i]);
     87             if(a[i]!=a[i-1]) d[i][0]=1;
     88             else d[i][0]=d[i-1][0]+1;
     89             
     90          }
     91            
     92         Num_init();  
     93         RMQ_init();
     94 
     95         while(q--) {
     96             scanf("%d%d",&x,&y);
     97             if(Left[x]==Left[y]) printf("%d
    ",y-x+1);
     98             else { 
     99                 if(Right[x]+1==Left[y]) printf("%d
    ",max(Right[x]-x+1,y-Left[y]+1));
    100                 else {       
    101                      RMQ(Right[x]+1,Left[y]-1);
    102                      printf("%d
    ",max(max(Right[x]-x+1,y-Left[y]+1),maxn));
    103                 }
    104             }
    105         }
    106     }   
    107     
    108     
    109     return 0;
    110 }
    
    
    
     
  • 相关阅读:
    HDU 1358 Period (KMP)
    POJ 1042 Gone Fishing
    Csharp,Javascript 获取显示器的大小的几种方式
    css text 自动换行的实现方法 Internet Explorer,Firefox,Opera,Safar
    Dynamic Fonts动态设置字体大小存入Cookie
    CSS Image Rollovers翻转效果Image Sprites图片精灵
    CSS three column layout
    css 自定义字体 Internet Explorer,Firefox,Opera,Safari
    颜色选择器 Color Picker,Internet Explorer,Firefox,Opera,Safar
    CSS TextShadow in Safari, Opera, Firefox and more
  • 原文地址:https://www.cnblogs.com/sxiszero/p/3913715.html
Copyright © 2011-2022 走看看