SP3946 MKTHNUM - K-th Number(整体二分)

Posted dreagonm

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SP3946 MKTHNUM - K-th Number(整体二分)相关的知识,希望对你有一定的参考价值。

思路

整体二分的板子题,没什么思路好说

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
struct Query{
    int type,pos,val,l,r,k,aid;
}Query[110000],lx[110000],rx[110000];
int ans[10000],n,m,qid,aid,minx=0x3f3f3f3f,maxx=-0x3f3f3f3f;
namespace BIT{
    int bit[110000];
    int lowbit(int x){
        return x&(-x);
    }
    void add(int pos,int val){
        while(pos<=n){
            bit[pos]+=val;
            pos+=lowbit(pos);
        }
    }
    int query(int pos){
        int ans=0;
        while(pos){
            ans+=bit[pos];
            pos-=lowbit(pos);
        }
        return ans;
    }
};
void divide(int L,int R,int l,int r){//L,R 值域 l,r 操作序列
    if(l>r)
        return;
    int lt=0,rt=0;
    if(L==R){
        for(int i=l;i<=r;i++)
            if(Query[i].aid)
                ans[Query[i].aid]=L;
        return;
    }
    int mid=(L+R)>>1;
    for(int i=l;i<=r;i++){
        if(Query[i].type==1){//修改
            if(Query[i].val<=mid){
                BIT::add(Query[i].pos,1);
                lx[++lt]=Query[i];
            }
            else
                rx[++rt]=Query[i];            
        }
        else{//查询
            int cnt=BIT::query(Query[i].r)-BIT::query(Query[i].l-1);
            if(cnt<Query[i].k){
                Query[i].k-=cnt;
                rx[++rt]=Query[i];
            }
            else
                lx[++lt]=Query[i];
        }
    }
    for(int i=l;i<=r;i++)
        if(Query[i].type==1&&Query[i].val<=mid)
            BIT::add(Query[i].pos,-1);
    for(int i=1;i<=lt;i++)
        Query[l+i-1]=lx[i];
    for(int i=1;i<=rt;i++)
        Query[l+lt+i-1]=rx[i];
    divide(L,mid,l,l+lt-1);
    divide(mid+1,R,l+lt,r);
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++){
        int x;
        scanf("%d",&x);
        Query[++qid].pos=i;
        Query[qid].type=1;
        Query[qid].val=x;
        maxx=max(maxx,x);
        minx=min(minx,x);
    }
    for(int i=1;i<=m;i++){
        Query[++qid].type=2;
        scanf("%d %d %d",&Query[qid].l,&Query[qid].r,&Query[qid].k);
        Query[qid].aid=++aid;
    }
    divide(minx,maxx,1,qid);
    for(int i=1;i<=m;i++)
        printf("%d
",ans[i]);
    return 0;
}

以上是关于SP3946 MKTHNUM - K-th Number(整体二分)的主要内容,如果未能解决你的问题,请参考以下文章

Spoj MKTHNUM - K-th Number

POJ 2104 K-th Number

POJ-2104 K-th Number CDQ分治

luogu P3946 ことりのおやつ 题解

luogu 3946 ことりのおやつ(小鸟的点心)

K-th Number