码迷,mamicode.com
首页 > 其他好文 > 详细

静态区间第k小 - 整体二分

时间:2020-02-07 17:01:40      阅读:67      评论:0      收藏:0      [点我收藏+]

标签:set   image   code   main   back   ack   +=   图片   bool   

蒟蒻终于学会整体二分啦!

思路

技术图片

实现

技术图片

丑陋无比的代码

#include <bits/stdc++.h>
using namespace std;

const int N = 200005;
int ar[N];
int lowbit(int t) { return t & (-t); }
void add(int i, int v) {
    for (; i < N; ar[i] += v, i += lowbit(i));
}
int sum(int i) {
    int s = 0;
    for (; i > 0; s += ar[i], i -= lowbit(i));
    return s;
}


struct Elem {
    int pos,val;
    bool operator < (const Elem &b) {
        return val < b.val;
    }
} e[200005];

struct Query {
    int l,r,k,ans;
} q[200005];

int n,m,a[200005];

void solve(int l,int r,vector<int> num,vector <int> v) {
    //cout<<l<<" "<<r<<" "<<num.size()<<" "<<v.size()<<endl;
    if(l==r) {
        for(int i=0;i<v.size();i++) {
            q[v[i]].ans = l;
        }
    }
    else {
        memset(ar,0,sizeof ar);
        vector <int> v1,v2,n1,n2;
        int mid = (l+r)>>1;
        for(int i=0;i<num.size();i++) {
            if(e[num[i]].val<=mid) {
                add(e[num[i]].pos,1);
                n1.push_back(num[i]);
            }
            else {
                n2.push_back(num[i]);
            }
        }
        for(int i=0;i<v.size();i++) {
            if(sum(q[v[i]].r)-sum(q[v[i]].l-1) >= q[v[i]].k) {
                v1.push_back(v[i]);
            }
            else {
                q[v[i]].k -= sum(q[v[i]].r)-sum(q[v[i]].l-1);
                v2.push_back(v[i]);
            }
        }
        if(v1.size()) solve(l,mid,n1,v1);
        if(v2.size()) solve(mid+1,r,n2,v2);
    }
}

int main() {
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) {
        scanf("%d",&a[i]);
        e[i].pos=i;
        e[i].val=a[i];
    }
    sort(e+1,e+n+1);
    for(int i=1;i<=m;i++) {
        scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k);
    }
    vector <int> tmp;
    vector <int> num;
    for(int i=1;i<=n;i++) {
        num.push_back(i);
    }
    for(int i=1;i<=m;i++) {
        tmp.push_back(i);
    }
    solve(-1e+9,1e+9,num,tmp);
    for(int i=1;i<=m;i++) {
        cout<<q[i].ans<<endl;
    }
}

静态区间第k小 - 整体二分

标签:set   image   code   main   back   ack   +=   图片   bool   

原文地址:https://www.cnblogs.com/mollnn/p/12273409.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!