初学主席树

来源:互联网 发布:js event button 编辑:程序博客网 时间:2024/05/29 02:31

关于知识点的请看链接(我翻了n个blog,就这个写的最明白):点击打开链接

代码:(区间第k大)

#include <cstdio>#include <iostream>#include <algorithm>#include <string>#define lson l, m#define rson m+1, rusing namespace std;const int N=1e5+5;int L[N<<5], R[N<<5], sum[N<<5];int tot;int a[N], T[N], Hash[N];int build(int l,int r){       int rt=(++tot);       sum[rt]=0;       if(l<r)       {           int m=(r+l)>>1;           L[rt]=build(lson);           R[rt]=build(rson);       }    return rt;}int update(int pre,int l,int r,int x){    int rt=(++tot);    L[rt]=L[pre],R[rt]=R[pre],sum[rt]=sum[pre]+1;    if(l<r)    {        int m=(r+l)>>1;        if(x<=m)        {            L[rt]=update(L[pre],lson,x);        }        else            R[rt]=update(R[pre],rson,x);    }    return rt;}int query(int u,int v,int l,int r,int k){    if(l>=r)        return l;    int m=(l+r)>>1;    int num=sum[L[v]]-sum[L[u]];    if(num>=k)    {        return query(L[u],L[v],lson,k);    }    else        return query(R[u],R[v],rson,k-num);}int main(){    int t;    scanf("%d",&t);    while(t--)    {        tot=0;        int n,m;        scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++)        {            scanf("%d",&a[i]);            Hash[i]=a[i];        }        sort(Hash+1,Hash+1+n);        int d=unique(Hash+1,Hash+1+n)-Hash-1;        T[0]=build(1,d);        for(int i=1;i<=n;i++)        {            int x=lower_bound(Hash+1,Hash+d+1,a[i])-Hash;            T[i]=update(T[i-1],1,d,x);        }        while(m--)        {            int l,r,k;            scanf("%d%d%d",&l,&r,&k);            int x=query(T[l-1],T[r],1,d,k);            printf("%d\n",Hash[x]);        }    }}
#include<stdio.h>#include<stdlib.h>#include<algorithm>#include<iostream>#include<vector>#include<map>#include<set>#include<math.h>#include<string.h>#define ll long longusing namespace std;const int N=1e6+6;vector<int>p;int cnt,n,m,x,y,k,root[N],a[N];struct node{int l,r,sum;}T[N*40];int getid(int x){ return lower_bound(p.begin(),p.end(),x)-p.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=(r+l)>>1;    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=(r+l)>>1;    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(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++) scanf("%d",&a[i]),p.push_back(a[i]);    sort(p.begin(),p.end()),p.erase(unique(p.begin(),p.end()),p.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++)    {        scanf("%d%d%d",&x,&y,&k);        printf("%d\n",p[query(1,n,root[x-1],root[y],k)-1]);    }    return 0;}


0 0