• POJ3368(RMQ,区间频率问题)


    Frequent values

    Time Limit: 2000 MS Memory Limit: 65536 KB

    64-bit integer IO format: %I64d , %I64u Java class name: Main

    [Submit] [Status] [Discuss]

    Description

    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

    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

    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

    Source

    Ulm Local 2007
    ****************************************************分割线********************************************************************************************
    RMQ的两个考法1便是正常求区间最小最大,2是求区间频率大小,然而区间的划分时会造成不完全的划分,我们只要分情况解决就好了,这里我们可以引用数组记录每一个数字出现后的首地址结束位置,
    并用数组记录这是第几个数,然后单独计算左右和中间,最后比较就好了,其实还是正常RMQ,代码实现不难但容易出错,要小心计算每一个位置。
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<math.h>
     4 #include<iostream>
     5 using namespace std;
     6 #define N 12220
     7 int re,r[N],l[N];
     8 int mark[N];
     9 ///mark chucundeshicishushishuyudijigeshu tabashuhedijigeshuxiangduiying
    10 ///left chucundeshicishushicongnalikaishi
    11 ///rigjt chucundeshicishushicongnalijieshu
    12 int num[N];///shijishuzuyijingxioashi,xianzai num baocundeshidejigeshuheyoujige
    13 int maxsum[N][20];
    14 void RMQ(){///zheyangdeRMQdedabufenchucundedaxiaoshicuowude,zhiyoushaoshucaishizhengquede,womenyaozaisouxunshizhaodaozhengquede.zheyangwomenjiukeyiluanpaile
    15     for(int i=1;i<=re;i++) maxsum[i][0]=num[i];
    16     for(int j=1;(1<<j)-1<=re;j++){
    17         for(int i=1;i+(1<<(j-1))-1<=re;i++)
    18             maxsum[i][j]=max(maxsum[i][j-1],maxsum[i+(1<<(j-1))-1][j-1]);
    19     }
    20 }
    21 int Max(int a,int b,int c){
    22     if(a<b) a=b;
    23     if(a<c) a=c;
    24     return a;
    25 }
    26 int main()
    27 {
    28     int n,q,i,j,k,L,R,val;
    29     while(scanf("%d",&n)!=EOF&&n){
    30         re=1;
    31         scanf("%d%d",&q,&k);
    32         val=k;
    33         num[1]=1;
    34         mark[1]=1;
    35         l[0]=1;
    36         for(i=2;i<=n;i++){
    37             scanf("%d",&k);
    38             if(k==val){
    39                 num[re]++;//zhesjitongyangdeshudedijige
    40                 mark[i]=re;//renweidiyiduan
    41             }
    42             else{
    43                 r[re]=i-1;///soudingshangyigeshudeyoubianjie
    44                 re++;///jinruxiayigeduan
    45                 mark[i]=re;///xiayiduanbianhao
    46                 l[re]=i;///xinyiduankaishidedifang
    47                 val=k;///biaojixiaygeshufangbianbijiao
    48                 num[re]=1;///xinshudediyigeshukaishi
    49             }
    50         }
    51         RMQ();
    52         while(q--){
    53             scanf("%d%d",&L,&R);
    54             if(mark[L]==mark[R]) printf("%d",R-L+1);//rugouzaitongyiqujian
    55             else{
    56                 int ans=0;
    57                 if(mark[L]+1<=mark[R]-1){//如果两段中存在段
    58                     //int k=(int)((log(mark[R]-1))/log(2.0));
    59                     int k=(int)((log(mark[R]-mark[L]-1))/log(2.0));
    60                     //ans=max(maxsum[mark[L]+1][k],maxsum[mark[R]-(1<<k)][k]);
    61                     ans=max(maxsum[mark[L]+1][k],maxsum[mark[R]-(1<<k)][k]);
    62                 }
    63                 ans=Max(r[mark[L]]-L+1,ans,R-l[mark[R]]+1);
    64                 //printf("%d-->%d-->%d
    ",r[mark[L]]-L+1,ans,R-l[mark[R]]+1);
    65                 printf("%d
    ",ans);
    66             }
    67         }
    68     }
    69 }

    这里好多注释都是用拼音注释的,不过都很好理解。

  • 相关阅读:
    内置函数(十)
    常用命令
    函数式编程(九)——map,filter,reduce
    函数(八)-函数和匿名函数
    设计模式(十三)——观察者模式
    Confluence 6 重要缓存和监控
    Confluence 6 数据中心的缓存
    Confluence 6 配置文件和key
    Confluence 6 缓存性能示例
    Confluence 6 缓存性能优化
  • 原文地址:https://www.cnblogs.com/VectorLin/p/5268174.html
Copyright © 2020-2023  润新知