• 【图灵杯 E也即POJ 3368】简单的RMQ


    Description
    给定一个数组,其中的元素满足非递减顺序。任意给定一个区间[i,j],求其中某个元素重复出现的最大次数。

    Input
    多组数据输入。每组数据的第一行包含两个整数n和q(1<=n,q<=100000),下一行包含n个整数a1,…,an(-100000<=ai<=100000,i∈{1,…,n}),用空格分隔,数列是升序的(ai<=ai+1)。接下来的q行,每行包含两个整数i和j(1<=i<=j<=n),表示给定区间[i,j]。
    输入结束于0(自成一行)。

    Output
    对输入的q个区间,每个区间输出一个整数表示该区间内重复最多的元素出现的次数,用换行分隔。

    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

    【题目链接】:http://oj.acmclub.cn/problem.php?cid=1162&pid=4

    【题意】

    【题解】

    构造一个数组b;

    if(a[i]==a[i-1])
        b[i] = b[i-1]+1;
    else
        b[i] = 1;


    这个b数组
    就表示第i个数字前面有多少个连续数字是和它相等的;
    这样对于每一个区间L,R
    除了最左端的b[L]以及右端的连续的a[i]==a[L]的位置不能肯定就一定有B[L]个以外,其他的都能确定出现次数最多的就是b的最大值;
    这里可以再O(N)求出从该位置开始往后连续的有多少长度和这个位置的a[i]相同;设为dp[i]
    则一开始令t=min(dp[L],R-L+1),L=L+dp[i];
    然后取【L,R】中的b的最大值和t取较大值作为答案;(L>R的话,答案就是t)

    【Number Of WA

    1

    【完整代码】

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    const int N = 1e5;
    int n, q;
    int a[N+5], b[N+5], mx[N<<2],dp[N+5];
    void build(int l,int r,int rt)
    {
        if(l==r)
        {
            mx[rt] = b[l];
            return ;
        }
        int m = (l+r)>>1;
        build(lson);
        build(rson);
        mx[rt] = max(mx[rt<<1], mx[rt<<1|1]);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        if(L<=l && r<=R)
            return mx[rt];
        int m = (l+r)>>1;
        int ans = 1;
        if(L<=m)
            ans = max(ans,query(L,R,lson));
        if(R>m)
            ans = max(ans,query(L,R,rson));
        return ans;
    }
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        //ios::sync_with_stdio(false);
        while(scanf("%d",&n)!=EOF)
        {
            if (n==0) break;
            scanf("%d",&q);
            a[0] = -1e7;
            memset(b,0,sizeof(b));
            for(int i=1; i<=n; ++i)
            {
                scanf("%d",&a[i]);
                if(a[i]==a[i-1])
                    b[i] = b[i-1]+1;
                else
                    b[i] = 1;
            }
            dp[n] = 1;
            for (int i = n-1;i >= 1;i--)
                if (a[i+1]==a[i]){
                    dp[i] = dp[i+1]+1;
                }
                else
                    dp[i] = 1;
            build(1,n,1);
            while(q--)
            {
                int L,R;
                scanf("%d%d",&L,&R);
                int t=0;
                t = min(dp[L],R-L+1);
                L = L + t;
                if(L>R)
                    printf("%d
    ",t);
                else
                    printf("%d
    ",max(t,query(L,R,1,n,1)));
            }
        }
    }
  • 相关阅读:
    hdu 4578 线段树 ****
    hdu 4576 概率dp **
    hdu 4622 **
    vue中保存和获取cookie,读写cookie以及设置有效时间等,使用js-cookie
    go语言 strconv.ParseInt 的例子
    【golang】unsafe.Sizeof浅析
    Golang 漫谈之channel妙法
    总结了才知道,原来channel有这么多用法!
    字符集之在UTF-8中,一个汉字为什么需要三个字节?
    什么是Bitmap
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626259.html
Copyright © 2020-2023  润新知