Kth number

模板题,题意是求区间第k大,套一下主席树模板或者划分树模板即可(屯板子)

代码如下:

主席树:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <list>
#include <set>
#include <utility>
#include <map>
#include <stack>
#include <cctype>
#include <string>
#include <queue>
#define mst(a,b) memset((a),(b),sizeof(a))
#define debug printf("debug\n")
#define INF 0x3f3f3f3f
#define IOS std::ios::sync_with_stdio(false)
const int maxn=1e5+5;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int rt[maxn<<5];
int sum[maxn<<5];
int ls[maxn<<5],rs[maxn<<5];
int tot;
int p;
void build(int lef,int rig,int& root)        //其实就是一个为各节点分配id的过程 
{
    root=++tot;
    if(lef==rig)    return ;
    int mid=lef+(rig-lef)/2;
    build(lef,mid,ls[root]);
    build(mid+1,rig,rs[root]);
}
int update(int lef,int rig,int root)        
{
    int root_=++tot;        //建一棵新树 
    ls[root_]=ls[root];
    rs[root_]=rs[root];
    sum[root_]=sum[root]+1;
    if(lef==rig)    return root_;
    int mid=lef+(rig-lef)/2;
    if(p<=mid){
        ls[root_]=update(lef,mid,ls[root_]);        //如果修改点在左儿子,就新建一个左儿子 
    }else{
        rs[root_]=update(mid+1,rig,rs[root_]);        //如果修改点在右儿子,就新建一个右儿子 
    }
    return root_;
}
int query(int u,int v,int lef,int rig,int k)
{
    int ans=0;
    int mid=lef+(rig-lef)/2;
    int x=sum[ls[v]]-sum[ls[u]];
    if(lef==rig)    return lef;
    if(x>=k){
        ans=query(ls[u],ls[v],lef,mid,k);
    }else{
        ans=query(rs[u],rs[v],mid+1,rig,k-x);
    }
    return ans;
}
int arr[maxn];
int lisan[maxn];
int main()
{
    tot=0;
    int n,m;cin>>n>>m;
    for(int i=1;i<=n;i++)    cin>>arr[i],lisan[i]=arr[i];
    sort(lisan+1,lisan+1+n);
    int len=unique(lisan+1,lisan+1+n)-lisan-1;
    build(1,len,rt[0]);
    for(int i=1;i<=n;i++){
        p=lower_bound(lisan+1,lisan+1+len,arr[i])-lisan;
        rt[i]=update(1,len,rt[i-1]);
    }
    int ans=0;
    for(int i=0;i<m;i++){
        int L,R,k;cin>>L>>R>>k;
        ans=query(rt[L-1],rt[R],1,len,k);
        cout<<lisan[ans]<<"\n";
    }
    return 0;
    
}

划分树:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <list>
#include <set>
#include <utility>
#include <map>
#include <stack>
#include <cctype>
#include <string>
#include <queue>
#define mst(a,b) memset((a),(b),sizeof(a))
#define debug printf("debug\n")
#define INF 0x3f3f3f3f
#define IOS std::ios::sync_with_stdio(false)
const int maxn=1e5+50;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int tree[20][maxn];
int to_lef[20][maxn]; 
int sorted[maxn];
void build(int lef,int rig,int lev)
{
    if(lef==rig) return ;
    int mid=lef+(rig-lef)/2; 
    int sup=mid-lef+1;
    for(int i=lef;i<=rig;i++){
        if(tree[lev][i]<sorted[mid]){
            sup--;
        }
    }
    int sublef=lef;int subrig=mid+1;
    for(int i=lef;i<=rig;i++){
        if(i==lef){
            to_lef[lev][i]=0;
        }else{
            to_lef[lev][i]=to_lef[lev][i-1];
        }
        if(tree[lev][i]<sorted[mid]||tree[lev][i]==sorted[mid]&&sup>0){
            tree[lev+1][sublef++]=tree[lev][i];
            to_lef[lev][i]++;
            if(tree[lev][i]==sorted[mid])    sup--;
        }else{
            tree[lev+1][subrig++]=tree[lev][i]; 
        }
    }
    build(lef,mid,lev+1);
    build(mid+1,rig,lev+1);
}
int query(int lev,int lef,int rig,int L,int R,int k)
{
    int mid=lef+(rig-lef)/2;
    if(L==R)    return tree[lev][L];
    int lef_,tolef;
    if(L==lef){
        lef_=0;tolef=to_lef[lev][R];
    }else{
        lef_=to_lef[lev][L-1];
        tolef=to_lef[lev][R]-lef_;
    }
    if(k<=tolef){
        int tmp_lef=lef+lef_;
        int tmp_rig=lef+lef_+tolef-1;
        return query(lev+1,lef,mid,tmp_lef,tmp_rig,k);
    }else{
        int tmp_lef=mid+L-lef-lef_+1;
        int tmp_rig=mid+R-lef-lef_-tolef+1;
        return query(lev+1,mid+1,rig,tmp_lef,tmp_rig,k-tolef);
    }
}
int main()
{
    int n,m;scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&sorted[i]);
        tree[0][i]=sorted[i];
    }
    sort(sorted+1,sorted+1+n);
    build(1,n,0);
    for(int i=0;i<m;i++){
        int x,y,k;scanf("%d %d %d",&x,&y,&k);
        int ans=query(0,1,n,x,y,k);
        printf("%d\n",ans);
    }
    return 0;
}