zoukankan      html  css  js  c++  java
  • Codeforces 1262D2

    Description

    思路

    对于D1的可以先按值排序,然后取前k个数按位置排序,取第p个的值。
    对于D2,把询问全部存起来,按k排序。这样只要选取一种数据结构,可以快速地处理“一次插入一个值,求其中第p大的数”的问题。

    这里可以选用树状数组来处理求第p大的数这样的问题。树状数组的位置x代表比x小于等于的数有多少,这样就可以用二分查找来确定第p大的数,复杂度为((log_2n)^2)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 1e6;
    #define inf 0x3f3f3f3f
    
    typedef pair<int, int> PII;
    PII a[N];
    PII q[N];
    int pos[N];
    int ans[N];
    int arr[N];
    int tarr[N];
    int n, m;
    
    bool cmp(const PII &a, const PII &b) {
        if(a.first == b.first) return a.second < b.second;
        return a.first > b.first;
    }
    
    int lowbit(int x) {return x & -x;}
    void addv(int p, int v) {
        while(p <= n) {
            tarr[p] += v;
            p += lowbit(p);
        }    
    }
    void add(int l, int r, int v) {
        addv(l, v);
        addv(r + 1, -v);
    }
    int get(int p) {
        int res = 0;
        while(p) {
            res += tarr[p];
            p -= lowbit(p);
        }
        return res;
    }
    
    int getpos(int p) { //小于等于 //取第p大的数
        int l = 1, r = n;
        while(l <= r) {
            int mid = (l + r) / 2;
            if(get(mid) < p) l = mid + 1;
            else r = mid - 1;
        }
        return l;
    }
    
    
    int main() {
        ios::sync_with_stdio(false);
        cin >> n;
        for(int i = 1; i <= n; i++) {
            int v;
            cin >> v;
            a[i - 1] = make_pair(v, i);
            arr[i] = v;
        }
        sort(a, a + n, cmp);
        cin >> m;
        for(int i = 0; i < m; i++) {
            int k, p;
            cin >> k >> p;
            q[i] = make_pair(k, i);
            pos[i] = p;
        } 
        sort(q, q + m);
        int cur = 0;
        for(int i = 0; i < m; i++) {
            while(cur != q[i].first) {
                add(a[cur].second, n, 1);
                cur++;
            }
            ans[q[i].second] = arr[getpos(pos[q[i].second])];
        }
        for(int i = 0; i < m; i++) {
            cout << ans[i] << endl;
        }
    }
    

    Update

    树状数组第k大的数可以用(log_2n)复杂度实现,见

  • 相关阅读:
    windows已经阻止此软件因为无法验证发行者解决方案
    vs用resharp如何调试到源码而不是对象浏览器
    Android环境变量的设置(详细图解版)
    js为xml添加节点和属性
    javascript操作xml文件综合实例
    js如何循环读取xml文件的节点
    游标的简单理解
    关于DATE函数datediff dateadd datename等
    分组数据where & having ,group by & order by
    SQL拼接字段,算数计算
  • 原文地址:https://www.cnblogs.com/limil/p/12649928.html
Copyright © 2011-2022 走看看