HDU - 2665 Kth number

Kth number

Problem Description
Give you a sequence and ask you the kth big number of a inteval.
 
Input
The first line is the number of the test cases. 
For each test case, the first line contain two integer n and m (n, m <= 100000), indicates the number of integers in the sequence and the number of the quaere. 
The second line contains n integers, describe the sequence. 
Each of following m lines contains three integers s, t, k. 
[s, t] indicates the interval and k indicates the kth big number in interval [s, t]
 
Output
For each test case, output m lines. Each line contains the kth big number.
 
Sample Input
1 10 1 1 4 2 3 5 6 7 8 9 0 1 3 2
 
Sample Output
2
 

主席树初始。题目意思是求区间第k大,但是求第k小的代码才能过。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000+10;
struct node
{
    int l,r,sum;
} tree[maxn*20];
int cnt,a[maxn],b[maxn],rt[maxn],n,m;
void build(int l,int r,int &x)
{
    x=++cnt;
    tree[x].sum=0;
    if(l==r) return ;
    int m=(l+r)>>1;
    build(l,m,tree[x].l);
    build(m+1,r,tree[x].r);
}
void updata(int l,int r,int pre,int &now,int k)
{
    now=++cnt;
    tree[now]=tree[pre];
    tree[now].sum++;
    if(l==r) return;
    int m=(l+r)>>1;
    if(k<=m) updata(l,m,tree[pre].l,tree[now].l,k);
    else updata(m+1,r,tree[pre].r,tree[now].r,k);

}
int query(int l,int r,int pre,int now,int k)
{
    if(l==r) return b[l];
    int m=(l+r)>>1;
    int sum=tree[tree[now].l].sum-tree[tree[pre].l].sum;
    if(k<=sum)return query(l,m,tree[pre].l,tree[now].l,k);
    else return query(m+1,r,tree[pre].r,tree[now].r,k-sum);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        cnt=0;
        scanf("%d %d",&n,&m);
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        sort(b+1,b+1+n);
        int len=unique(b+1,b+1+n)-(b+1);
        for(int i=1; i<=n; i++) a[i]=lower_bound(b+1,b+1+len,a[i])-b;
        build(1,len,rt[0]);
        for(int i=1; i<=n; i++) updata(1,len,rt[i-1],rt[i],a[i]);
        while(m--)
        {
            int l,r,k;
            scanf("%d %d %d",&l,&r,&k);
            printf("%d\n",query(1,len,rt[l-1],rt[r],k));
        }
    }
}

PS:摸鱼怪的博客分享,欢迎感谢各路大牛的指点~

猜你喜欢

转载自www.cnblogs.com/MengX/p/9100639.html