zoukankan      html  css  js  c++  java
  • HDU 1806 Frequent values(RMQ)

    Frequent values

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 778    Accepted Submission(s): 259


    Problem 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
    Hint
    A naive algorithm may not run in time!
     
    Source
     
    Recommend
    linle
     
     
    此题用线段树做也是挺方便的。
    用了ST的RMQ做,速度挺快的。
     
    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    using namespace std;
    const int MAXN=100010;
    
    int a[MAXN];
    int b[MAXN];
    int dp[MAXN][20];
    
    void makeRMQ(int n,int b[])
    {
        for(int i=0;i<n;i++)
          dp[i][0]=b[i];
        for(int j=1;(1<<j)<=n;j++)
          for(int i=0;i+(1<<j)-1<n;i++)
            dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
    }
    int rmq(int s,int v)
    {
        int k=(int)(log(v-s+1.0)/log(2.0));
        return max(dp[s][k],dp[v-(1<<k)+1][k]);
    }
    
    int bi_search(int s,int t)
    {
        int tmp=a[t];
        int l=s;
        int r=t;
        int mid;
        while(l<r)
        {
            mid=((l+r)>>1);
            if(a[mid]>=tmp)r=mid;
            else l=mid+1;
        }
        return r;
    }
    
    int main()
    {
      //  freopen("in.txt","r",stdin);
      //  freopen("out.txt","w",stdout);
        int n,q;
        int s,t;
        while(scanf("%d",&n),n)
        {
            scanf("%d",&q);
            for(int i=0;i<n;i++)
              scanf("%d",&a[i]);
            int tmp;
            for(int i=n-1;i>=0;i--)
            {
                if(i==n-1)tmp=1;
                else
                {
                    if(a[i]==a[i+1])tmp++;
                    else tmp=1;
                }
                b[i]=tmp;
            }
            makeRMQ(n,b);
            while(q--)
            {
                scanf("%d%d",&s,&t);
                s--;
                t--;
                /*int ans=1;
                t--;
                while(s<=t)
                {
                    if(a[t]!=a[t+1])break;
                    ans++;
                    t--;
                }*/
                int temp=bi_search(s,t);//找到区间中值和右端点相同的位置
                int ans=t-temp+1;
                t=temp-1;
                if(s>t)printf("%d\n",ans);
                else printf("%d\n",max(ans,rmq(s,t)));
            }
        }
        return 0;
    }
  • 相关阅读:
    使pre的内容自动换行
    textarea文本换行和页面显示换行符
    SQL查询包含汉字的行
    网站引导页插件intro.js 的用法
    jquery.cookie中的操作
    sql自动生成汉语拼音和首字母函数
    IE,Chrome滚动条样式CSS
    Vcenter server 5.5上传ISO镜像
    Vcenter server 5.5添加用户角色及分配权限
    Vcenter server 5.5安装部署
  • 原文地址:https://www.cnblogs.com/kuangbin/p/2696052.html
Copyright © 2011-2022 走看看