zoukankan      html  css  js  c++  java
  • poj3368--Frequent values--不递减数列的区间众数--RMQ问题

    Description

    给一个不递减的长度为n的数列,q个询问,每次询问[l,r]区间内众数出现的次数。

    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

    题解:

      因为是有了不递减的限制,所以可以当成rmq问题来解决,还是用st算法。

      st[i][0]要记录出现次数,额外需要加一个关于断点前后各自的众数的大小的判断。因为数列不递减,(使断点和断点后一个数不相等,即在当前情况下尽可能使断点靠后)所以如果断点后出现的次数,比断点前的多,那么更新ans(取两者max)

      

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<cstdio>
     5 using namespace std;
     6 const int maxn=100009;
     7 int a[maxn],st[maxn][20],n,q;
     8 int sum[maxn],l,r;
     9 void init_st()
    10 {
    11     for(int i=n;i>=1;i--)
    12     {
    13         st[i][0]=sum[i];
    14         for(int j=1;(i+(1<<j)-1)<=n;j++)
    15         {
    16             st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);
    17         }
    18     }
    19 }
    20 int ask(int l,int r)
    21 {
    22     if(l>r)return 0;
    23     int k=((int)(log(r-l+1.0)/log(2.0)));
    24     return max(st[l][k],st[r-(1<<k)+1][k]);
    25 }
    26 int main()
    27 {
    28     while(scanf("%d",&n)!=EOF)
    29     {
    30         if(n==0)break;
    31         scanf("%d",&q);
    32         for(int i=1;i<=n;i++)
    33         {
    34             scanf("%d",&a[i]);
    35             if(i==1)
    36             {
    37                 sum[i]=1;
    38                 continue;
    39             }
    40             if(a[i]==a[i-1])
    41                 sum[i]=sum[i-1]+1;
    42             else
    43                 sum[i]=1;
    44         }
    45         init_st();
    46         while(q--)
    47         {
    48             scanf("%d%d",&l,&r);
    49             int tmp=l;
    50             while(a[tmp]==a[tmp-1]&&tmp<=r) tmp++;
    51             int cnt=ask(tmp,r);
    52             int ans=max(cnt,tmp-l);
    53             printf("%d
    ",ans);
    54         }
    55     }
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    BigTale
    GFS Google File System(中文翻译)
    MapReduce
    Google MapReduce/GFS/BigTable三大技术的论文中译版
    Linux常用命令大全
    linux常用命令
    Oracle复杂查询
    jquery on事件jquery on实现绑定多个事件
    Java 多线程(六) synchronized关键字详解
    什么才算是真正的编程能力?
  • 原文地址:https://www.cnblogs.com/Beckinsale/p/7465697.html
Copyright © 2011-2022 走看看