划分树

作者: 影踪派熊猫人武僧 | 来源:发表于2019-04-07 10:02 被阅读0次

    include<bits/stdc++.h>

    define int long long

    define maxn 500000

    using namespace std;
    inline char get(){
    static char buf[30000],p1=buf,p2=buf;
    return p1==p2 && (p2=(p1=buf)+fread(buf,1,30000,stdin),p1==p2)?EOF:p1++;
    }
    inline int read(){
    register char c=get();register int f=1,=0;
    while(c>'9' || c<'0')f=(c=='-')?-1:1,c=get();
    while(c<='9' && c>='0')
    =(<<3)+(<<1)+(c^48),c=get();
    return _
    f;
    }
    int n,m;
    int num[20][maxn],val[20][maxn],a[maxn];
    void build(int id,int l,int r){
    if(l==r)return;
    int mid=(l+r)>>1;
    int sameMid=0;
    for(register int i=l;i<=r;i++){
    if(a[i]==a[mid])sameMid++;
    else if(a[i]>a[mid])break;
    }
    int cas_l=l,cas_r=mid+1;
    for(register int i=l;i<=r;i++){
    if(i==l)num[id][i]=0;
    else num[id][i]=num[id][i-1];
    if(val[id][i]<a[mid] || (sameMid>0 && val[id][i]==a[mid])){
    val[id+1][cas_l++]=val[id][l];
    num[id][i]++;
    if(val[id][i]==a[mid])sameMid--;
    else val[id+1][cas_r++]=val[id][i];
    }
    }
    build(id+1,l,mid);
    build(id+1,mid+1,r);
    }
    int query(int id,int l,int r,int x,int y,int k){
    int mid=(l+r)>>1;
    if(l==r)return val[id][r];
    int fl=0;
    if(l!=x)fl=num[id][x-1];
    int cnt=num[id][y]-fl;
    if(cnt>=k)return query(id+1,l,mid,l+fl,l+num[id][y]-1,k);
    else{
    int pos_r=mid+1+(x-l-fl);
    return query(id+1,mid+1,r,pos_r,pos_r+y-x-cnt,k-cnt);
    }
    }
    signed main(){
    //freopen("1.txt","r",stdin);
    n=read(),m=read();
    for(register int i=1;i<=n;i++)a[i]=read(),val[0][i]=a[i];
    sort(a+1,a+1+n);
    build(0,1,n);
    while(m--){
    int l=read(),r=read(),k=read();
    cout<<query(0,1,n,l,r,k)<<endl;
    }
    return 0;
    }

    相关文章

      网友评论

          本文标题:划分树

          本文链接:https://www.haomeiwen.com/subject/nmvjiqtx.html