取板粗   好东西来的

 

1.(HDOJ2665)http://acm.hdu.edu.cn/showproblem.php?pid=2665

(POJ2104)http://poj.org/problem?id=2104

(POJ2761)http://poj.org/problem?id=2761

题意:求区间第K大,主席树模板题

 

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=200010;
int tot,n,q,nowm;
int a[maxn],t[maxn];
int c[maxn<<5],lson[maxn<<5],rson[maxn<<5];
int T[maxn];

void init_hash()
{
    for ( int i=1;i<=n;i++ ) t[i]=a[i];
    sort(t+1,t+1+n);
    nowm=unique(t+1,t+1+n)-(t+1);
}

int hash_(int x)
{
    return lower_bound(t+1,t+1+nowm,x)-t;
}

void build(int &root,int l,int r)
{
    root=++tot;
    if ( l==r ) return;
    int mid=(l+r)/2;
    build(lson[root],l,mid);
    build(rson[root],mid+1,r);
}

void update(int root,int &rt,int p,int val,int l,int r)
{
    rt=++tot;
    lson[rt]=lson[root],rson[rt]=rson[root];
    c[rt]=c[root]+val;
    if ( l==r ) return;
    int mid=(l+r)/2;
    if ( p<=mid ) update(lson[rt],lson[rt],p,val,l,mid);
    else update(rson[rt],rson[rt],p,val,mid+1,r);
}

int query(int rt_,int rt,int l,int r,int k)
{
    if ( l==r ) return l;
    int mid=(l+r)/2;
    int sum=c[lson[rt_]]-c[lson[rt]];
    if ( sum>=k ) return query(lson[rt_],lson[rt],l,mid,k);
    else return query(rson[rt_],rson[rt],mid+1,r,k-sum);
}

int main()
{
    int Case;
    scanf("%d",&Case);
    while(Case++){
        scanf("%d%d",&n,&q);
        tot=0;
        for ( int i=1;i<=n;i++ ) scanf("%d",&a[i]);
        init_hash();
        build(T[0],1,nowm);
        for ( int i=1;i<=n;i++ )
        {
            int pos=hash_(a[i]);
            update(T[i-1],T[i],pos,1,1,nowm);
        }
        while ( q-- )
        {
            int l,r,k;
            scanf("%d%d%d",&l,&r,&k);
            printf("%d\n",t[query(T[r],T[l-1],1,nowm,k)]);
        }
    }
    return 0;
}
View Code

相关文章: