zoukankan      html  css  js  c++  java
  • 图灵杯 E 简单的RMQ(UVA 11235)(RMQ)

     E: 简单的RMQ

    时间限制: 2 Sec  内存限制: 64 MB
    提交: 934  解决: 165
    [提交][状态][讨论版]

    题目描述

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

    输入

    多组数据输入。每组数据的第一行包含两个整数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(自成一行)。

    输出

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

    样例输入

    10 3
    -1 -1 1 1 1 1 3 10 10 10
    2 3
    1 10
    5 10
    0

    样例输出

    1
    4
    3
    【分析】直接区间RMQ,需要注意的是更新和查找时判一下两区间交点处的情况。
    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define met(a,b) memset(a,b,sizeof a)
    #define pb push_back
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int N = 2e5+50;
    const int mod = 1e9+7;
    const double pi= acos(-1.0);
    typedef pair<ll,int>pii;
    int mx[N][18];
    int mm[N],n,q;
    int l[N],r[N],a[N];
    void init() {
        for(int j=1; j<=mm[n]; ++j) {
            for(int i=1; i+(1<<j)-1<=n; ++i) {
                int mid=i+(1<<(j-1));
                int ll=max(i,l[a[mid]]);
                int rr=min(i+(1<<j)-1,r[a[mid]]);
                mx[i][j]=max(rr-ll+1,max(mx[i][j-1],mx[i+(1<<(j-1))][j-1]));
            }
        }
    }
    int getmx(int ll,int rr) {
        int k = mm[rr-ll+1];
        int l1=max(ll,l[a[ll+(1<<k)]]);
        int r1=min(rr,r[a[ll+(1<<k)]]);
        int l2=max(ll,l[a[rr-(1<<k)+1]]);
        int r2=min(rr,r[a[rr-(1<<k)+1]]);
        int ret=1;
        ret=max(r1-l1+1,r2-l2+1);
        ret=max(ret,max(mx[ll][k],mx[rr-(1<<k)+1][k]));
        return ret;
    }
    int main() {
        mm[0]=-1;
        for(int i=1; i<N; ++i)mm[i]=(i&(i-1))?mm[i-1]:mm[i-1]+1;
        while(~scanf("%d",&n)&&n) {
            met(l,0);
            scanf("%d",&q);
            for(int i=1; i<=n; ++i) {
                scanf("%d",&a[i]);
                a[i]+=100000;
                if(!l[a[i]])l[a[i]]=i;
                r[a[i]]=i;
                mx[i][0]=1;
            }
            init();
            while(q--) {
                int x,y;
                scanf("%d%d",&x,&y);
                printf("%d
    ",getmx(x,y));
            }
        }
        return 0;
    }
  • 相关阅读:
    POJ-3468 A Simple Problem with Integers(线段树、段变化+段查询、模板)
    CSUOJ-1978 LXX的图论题(最短路、Bellman-Ford判断负圈)
    CSU-1975 机器人搬重物(BFS)
    POJ-3522 Slim Span(最小生成树)
    POJ-1733 Parity game (并查集)
    libmysqlclient.so.16未找到方法
    python 不同目录间的模块调用
    python模块详解 logging
    python模块详解 re
    python模块详解 hashlib
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/6986669.html
Copyright © 2011-2022 走看看