poj2104 主席树+离散化

题意:给出一段数列(1e6),让你求[L,R]区间内第k小的数是多少(询问次数5e3)

思路:不带修改的主席树

离散化是按照qsc的思路来写的:

真实数据转换成离散化后的下标即为1,2,3...

离散化后的下标要转换成原来的数下标要减1

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=1e5+6;
int n,m,cnt,root[maxn],a[maxn],x,y,k;
vector<int>v;
int getid(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i],v.push_back(a[i]);
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
    return 0;
}

具体代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int maxn=1e5+6;
int n,m,cnt,root[maxn],a[maxn],x,y,k;//cnt主席树,a[maxn]代表每一个数,x,y,k代表询问
struct node{int l,r,sum;}T[maxn*40];

vector<int>v;
int getid(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}

void update(int l,int r,int &x,int y,int pos){  //&必须写!
    T[++cnt]=T[y],T[cnt].sum++,x=cnt;
    if(l==r) return;
    int mid=(l+r)/2;
    if(mid>=pos) update(l,mid,T[x].l,T[y].l,pos);
    else update(mid+1,r,T[x].r,T[y].r,pos);
}

int query(int l,int r,int x,int y,int k){
    if(l==r) return l;
    int mid=(l+r)/2;
    int sum=T[T[y].l].sum-T[T[x].l].sum;
    if(sum>=k) return query(l,mid,T[x].l,T[y].l,k);
    else return query(mid+1,r,T[x].r,T[y].r,k-sum);
}

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i],v.push_back(a[i]);
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
    for(int i=1;i<=n;i++)
        update(1,n,root[i],root[i-1],getid(a[i]));
    for(int i=1;i<=m;i++){
        cin>>x>>y>>k;
        cout<<v[query(1,n,root[x-1],root[y],k)-1]<<endl;
    }
    //for(int i=0;i<=n;i++)
      //  cout<<getid(i)<<endl;
    return 0;
}

reference:https://blog.csdn.net/creatorx/article/details/75446472

                   http://www.cnblogs.com/gryzy/p/6249193.html

                   https://www.cnblogs.com/oyking/p/3230296.html

more:https://blog.csdn.net/jerans/article/details/75807666

猜你喜欢

转载自blog.csdn.net/qq_40038776/article/details/82730624