• 2022百度之星程序设计大赛 - 初赛 - 第二场 1001 和


    problem

    在这里插入图片描述
    在这里插入图片描述

    solution

    题意:

    • 给出长为n的序列,q次询问区间是否存在<=k个数之和>=x。
    • n,q < 1e5, k <10.

    思路:

    • 因为要和>=x,所以让和尽可能大,即判断区间中最大的k个数之和是否大于x即可。
    • 即区间最大,倒数第2大,倒数第3大,倒数第k大之和即可,k<10,可以暴力。
    • 对于区间从小到大第x个数(即第x大的数),主席树板子即可,复杂度O(qklogn)。
    #include
    using namespace std;
    const int N = 100000 + 5;
    
    int a[N], b[N], rt[N * 20], ls[N * 20], rs[N * 20], sum[N * 20];
    int n, k, tot, sz, ql, qr, x, q, T;
    int kk, xx;
    
    void Build(int& o, int l, int r){
        o = ++ tot;
        sum[o] = 0;
        if(l == r) return;
        int m = (l + r) >> 1;
        Build(ls[o], l, m);
        Build(rs[o], m + 1, r);
    }
    void update(int& o, int l, int r, int last, int p){
        o = ++ tot;
        ls[o] = ls[last];
        rs[o] = rs[last];
        sum[o] = sum[last] + 1;
        if(l == r) return;
        int m = (l + r) >> 1;
        if(p <= m)  update(ls[o], l, m, ls[last], p);
        else update(rs[o], m + 1, r, rs[last], p);
    }
    int query(int ss, int tt, int l, int r, int k){
        if(l == r) return l;
        int m = (l + r) >> 1;
        int cnt = sum[ls[tt]] - sum[ls[ss]];
        if(k <= cnt) return query(ls[ss], ls[tt], l, m, k);
        else return query(rs[ss], rs[tt], m + 1, r, k - cnt);
    }
    void work(){
        scanf("%d%d", &ql, &qr);
        int len = (qr-ql+1);
        int res = 0;
        for(int i = len; i > len-kk; i--){
            //从小到大第i个数
            int ans = query(rt[ql - 1], rt[qr], 1, sz, i); 
            res += b[ans];
        }
        if(res >= xx)printf("Y\n");
        else printf("N\n");
    }
    int main(){
        scanf("%d%d%d%d", &n, &q, &kk, &xx);
        for(int i = 1; i <= n; i ++) scanf("%d", a + i), b[i] = a[i];
        sort(b + 1, b + n + 1);
        sz = unique(b + 1, b + n + 1) - (b + 1);
        tot = 0;
        Build(rt[0],1, sz);
        for(int i = 1; i <= n; i ++)a[i] = lower_bound(b + 1, b + sz + 1, a[i]) - b;
        for(int i = 1; i <= n; i ++)update(rt[i], 1, sz, rt[i - 1], a[i]);
        while(q --)work();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
  • 相关阅读:
    小程序富文本解析(mp-html组件)
    Zip密码忘记了,如何破解密码?
    vue混入(mixin)的详解
    flowable工作流所有业务概念
    为什么说使用领英的人一定要用领英精灵
    2023秋招大疆C++开发笔试
    Java面向对象编程
    Matlab论文插图绘制模板第65期—带等高线的曲面图(Surfc)
    Go for Add a Test for 20230921 Day2
    c++视觉处理---霍夫变换
  • 原文地址:https://blog.csdn.net/qq_33957603/article/details/126571261