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

    Frequent values
     
    You are given a sequence of n integers a 1 , a 2 , ... , a n 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 a i , ... , a j . 

    InputThe 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 a 1 , ... , a n(-100000 ≤ a i ≤ 100000, for each i ∈ {1, ..., n}) separated by spaces. You can assume that for each i ∈ {1, ..., n-1}: a i ≤ a i+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. 

    OutputFor 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! 

    题意:查询区间[l,r]中众数的个数.

    因为数列是非递减的,所以可以转化为ST表.

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #define N 100005
    using namespace std;
    int maxn[N][64],a[N],pre[N];
    int n,q,i,j;
    int main()
    {
        while(scanf("%d",&n)!=EOF&&n)
        {
            scanf("%d",&q);
            memset(maxn,0,sizeof maxn);
            for(i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                if(i==1)
                {
                    pre[i]=1;
                    continue;
                }
                if(a[i]==a[i-1])
                pre[i]=pre[i-1]+1;
                else
                pre[i]=1;
            }
            for(i=1;i<=n;i++)
            maxn[i][0]=pre[i];
            int t=log2(n);
            for(j=1;j<=t;j++)
            {
                for(i=1;i+(1<<j)-1<=n;i++)
                {
                    maxn[i][j]=max(maxn[i][j-1],maxn[i+(1<<(j-1))][j-1]);
                }
            }
            while(q--)
            {
                int MAX;
                int l,r; 
                scanf("%d%d",&l,&r);
                int m=l;
                while(m<=r&&a[m]==a[m-1])//区间第一个数字要特判. 
                m++;
                if(r<m)
                MAX=0;
                else
                { 
                    int k=log(r-m+1)/log(2);
                    MAX=max(maxn[m][k],maxn[r-(1<<k)+1][k]);
                } 
                MAX=max(MAX,m-l);
                printf("%d
    ",MAX);
            } 
        }
    } 
    View Code
  • 相关阅读:
    查看git submodule更改
    /var/lib/docker空间占用过大迁移
    docker -修改容器
    docker重命名镜像repository和tag
    方法的重写、重载。
    方法的声明与使用。
    二维数组。
    标准输入输出流概述和输出语句。
    冒泡排序法。
    IO流,对象操作流优化。
  • 原文地址:https://www.cnblogs.com/switch-waht/p/11396907.html
Copyright © 2011-2022 走看看