zoukankan      html  css  js  c++  java
  • POJ 3368 Frequent values(RMQ)

    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

    题意:

    给出N个数和Q次询问区间[L,R],对于每个询问,找到区间内连续出现最多次的数,输出该次数。

    题解:

    首先将每个数的连续出现次数存入数组f[i],对于所询问区间内,将最左子区间的连续且相同数进行特殊处理,单独计算该数在此区间的次数,然后计算此区间内除该数外的rmq,两者取最值即可。

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int MAX=100005;
    int dp[MAX][20],mm[MAX],f[MAX];
    void initrmq(int n,int b[])
    {
        mm[0]=-1;
        for(int i=1;i<=n;i++)
        {
            mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
            dp[i][0]=f[i];
        }
        for(int j=1;j<=mm[n];j++)
            for(int i=1;i+(1<<j)-1<=n;i++)
                dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
    }
    int rmq(int x,int y)
    {
        int k=mm[y-x+1];
        return max(dp[x][k],dp[y-(1<<k)+1][k]);
    }
    int main()
    {
        int n,q,i;
        while(scanf("%d",&n)&&n)
        {
            scanf("%d",&q);
            int b[MAX];
            for(i=1;i<=n;i++)
            {
                scanf("%d",&b[i]);
                if(i==1)
                {
                    f[i]=1;
                    continue;
                }
                if(b[i]==b[i-1])
                    f[i]=f[i-1]+1;
                else f[i]=1;
            }
            initrmq(n,f);
            for(i=1;i<=q;i++)
            {
                int l,r;
                scanf("%d%d",&l,&r);
                int tl=l;
                while(tl<=r&&b[tl]==b[tl-1])tl++;
                printf("%d
    ",max(tl-l,rmq(tl,r)));
            }
        }
        return 0;
    }
  • 相关阅读:
    servlet乱码以及解决
    javascript正则简单入门
    javascript创建自定义对象和prototype
    java 对象初始化和代码块初始化顺序
    java final 和instanceof 关键字
    【记录】自学JavaScript第七周
    【记录】自学JavaScript第六周
    获取节点名称及节点值
    正则表达式中的替换字符串示例
    部分正则表达式基本函数用法示例
  • 原文地址:https://www.cnblogs.com/kannyi/p/9807689.html
Copyright © 2011-2022 走看看