HDU 2665 Kth number(可持续化线段树)

来源:互联网 发布:2017微信数据报告 编辑:程序博客网 时间:2024/05/29 03:20

Kth number

Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9213    Accepted Submission(s): 2868


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大还有一个方法就是可持久化线段树,
这里由于给的值可能是负数,必须离散化,而且离散化之后的线段树空间可以开的更小一点
防止内存超限
#include <iostream>#include <string.h>#include <stdlib.h>#include <algorithm>#include <math.h>#include <stdio.h>#include <map>using namespace std;const int maxn=1e5;int rt[maxn+5];int ls[maxn*18+5];int rs[maxn*18+5];int sum[maxn*18+5];int b[maxn+5];int a[maxn+5];int n,m;int l,r;int p;map<int,int> m1,m2;void update(int &node,int l,int r,int val){    if(!node)    {        sum[p]=ls[p]=rs[p]=0;        node=p;        p++;    }    else    {        sum[p]=sum[node];ls[p]=ls[node];        rs[p]=rs[node];node=p;        p++;    }    if(l==r)    {        sum[node]++;        return;    }    sum[node]++;    int mid=(l+r)>>1;    if(val<=mid) update(ls[node],l,mid,val);    else update(rs[node],mid+1,r,val);}int query(int node1,int node2,int l,int r,int k){    if(sum[node2]-sum[node1]<k) return -1;    if(l==r) return l;    int mid=(l+r)>>1;    int num=sum[ls[node2]]-sum[ls[node1]];    if(num>=k)        return query(ls[node1],ls[node2],l,mid,k);    else        return query(rs[node1],rs[node2],mid+1,r,k-num);}int main(){    int t;    scanf("%d",&t);    int s,e,k;    while(t--)    {        l=1e9;r=0;        m1.clear();        m2.clear();        scanf("%d%d",&n,&m);        p=1;        for(int i=1;i<=n;i++)        {            scanf("%d",&b[i]);            a[i]=b[i];        }        sort(b+1,b+n+1);        for(int i=1;i<=n;i++)        {            m1[b[i]]=i;            m2[i]=b[i];        }        l=1,r=n;        update(rt[1]=0,l,r,m1[a[1]]);        for(int i=2;i<=n;i++)            update(rt[i]=rt[i-1],l,r,m1[a[i]]);        int ans;        for(int i=1;i<=m;i++)        {            scanf("%d%d%d",&s,&e,&k);            ans=query(rt[s-1],rt[e],l,r,k);            printf("%d\n",m2[ans]);        }    }    return 0;}



 

0 0
原创粉丝点击