• UPC10807: 发财兔序列


    题目描述

    给定一个非降序的由 n 个整数(int)构成的序列以及 q 个由整数(int)i 和 j 构成
    的询问。对于每一个询问,输出在 a[i],a[i+1], ... ,a[j-1],a[j]里面出现次
    数最多的那个(些)整数出现的次数。 

    输入

    第一行包含两个整数, n 和 q。 
    第二行包括 n 个整数 a[1],a[2], ... ,a[n],由空格分开。 
    以下 q 行每一行包括一个询问,一个询问由两个整数 i 和 j 构成,i 和 j 指示询问索引的边界。保证 i<=j。 

    输出

    对于每一组询问,输出一行一个整数:在给定区间内出现次数最多的那个(些)整数出现的次数。 

    样例输入

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

    样例输出

    1
    4
    3
    

    提示

     
     
    #include "bits/stdc++.h"
    
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5 + 1000;
    struct node {
        int l, r, p;
    } data[maxn];
    int cnt[maxn];
    int value[maxn];
    int dp[maxn][60];
    int n, q, p;
    
    void init() {
        for (int i = 0; i < n; i++) {
            dp[i][0] = cnt[i];
        }
        int k = (int) (log(n * 1.0) / log(2.0));
        for (int j = 1; j <= k; j++) {
            for (int i = 1; i + (1 << j) <= p + 1; i++) {
                dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
            }
        }
    }
    
    int rmq(int i, int j) {
        int m = (int) (log((double) (j - i + 1)) / log(2.0));
        int x = max(dp[i][m], dp[j - (1 << m)+1][m]);
        return x;
    }
    
    int main() {
        freopen("input.txt", "r", stdin);
        scanf("%d %d", &n, &q);
        int l = 0, r = 0, v = 0, t;
        p = 1;
        for (int i = 1; i <= n; i++) {
            scanf("%d", &t);
            if (t != v && l != 0) {
                cnt[p] = r - l + 1;
                value[p] = t;
                for (int j = l; j <= r; j++) {
                    data[j].l = l;
                    data[j].r = r;
                    data[j].p = p;
                }
                p++;
                r++;
                l = r;
                v = t;
            } else
                r++;
            if (l == 0) {
                l = 1;
                v = t;
            }
        }
        cnt[p] = r - l + 1;
        value[p] = v;
        for (int i = l; i <= r; i++) {
            data[i].l = l;
            data[i].r = r;
            data[i].p = p;
        }
        init();
        while (q--) {
            scanf("%d %d", &l, &r);
            if (data[l].p == data[r].p) {
                printf("%d
    ",r-l+1);
    
            } else {
                int ll = data[l].p + 1;
                int rr = data[r].p - 1;
                int ans = data[l].r - l + 1;
                ans = max(ans, r - data[r].l + 1);
                if (ll <= rr) {
                    ans = max(ans, rmq(ll, rr));
                }
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    正则表达式(四)--文本换行分割
    java加密类型和算法名称
    记事本记录日志
    DNS
    jstl--c:choose标签
    csv文本编辑引号问题
    JDBC----ReflectionUtils
    Jsp
    计算机网络 编程 总结:
    N颗骰子的问题
  • 原文地址:https://www.cnblogs.com/albert-biu/p/10337516.html
Copyright © 2020-2023  润新知