POJ 2104 划分树

来源:互联网 发布:mac卸载cuda 编辑:程序博客网 时间:2024/05/16 11:04
K-th NumberTime Limit: 20000MS     Memory Limit: 65536KTotal Submissions: 49923        Accepted: 16939Case Time Limit: 2000MSDescriptionYou are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array segment.That is, given an array a[1...n] of different integer numbers, your program must answer a series of questions Q(i, j, k) in the form: "What would be the k-th number in a[i...j] segment, if this segment was sorted?"For example, consider the array a = (1, 5, 2, 6, 3, 7, 4). Let the question be Q(2, 5, 3). The segment a[2...5] is (5, 2, 6, 3). If we sort this segment, we get (2, 3, 5, 6), the third number is 5, and therefore the answer to the question is 5.InputThe first line of the input file contains n --- the size of the array, and m --- the number of questions to answer (1 <= n <= 100 000, 1 <= m <= 5 000).The second line contains n different integer numbers not exceeding 109 by their absolute values --- the array for which the answers should be given.The following m lines contain question descriptions, each description consists of three numbers: i, j, and k (1 <= i <= j <= n, 1 <= k <= j - i + 1) and represents the question Q(i, j, k).OutputFor each question output the answer to it --- the k-th number in sorted a[i...j] segment.Sample Input7 31 5 2 6 3 7 42 5 34 4 11 7 3Sample Output563HintThis problem has huge input,so please use c-style input(scanf,printf),or you may got time limit exceed.SourceNortheastern Europe 2004, Northern Subregion
#include <cstdio>#include <iostream>#include <cmath>#include <algorithm>#include <cstring>#include <string>#include <cstdlib>#include <set>#include <queue>#include <vector>#include <map>using namespace std;typedef long long LL;#define MAXN 120000int Sorted[MAXN];int Tree[30][MAXN];int Toleft[30][MAXN];void Build(int Lef,int Rig,int dep){    if(Lef == Rig) return;    int Mid = (Lef+Rig)>>1;    int Same = Mid - Lef + 1;    for(int i=Lef;i<=Rig;i++)        if(Tree[dep][i]<Sorted[Mid]) Same--;    int Lpos = Lef;    int Rpos = Mid+1;    for(int i=Lef;i<=Rig;i++)    {        if(Tree[dep][i]<Sorted[Mid])            Tree[dep+1][Lpos++] = Tree[dep][i];        else if(Tree[dep][i]==Sorted[Mid] && Same>0)        {            Tree[dep+1][Lpos++] = Tree[dep][i];            Same--;        }        else Tree[dep+1][Rpos++] = Tree[dep][i];        Toleft[dep][i] = Toleft[dep][Lef-1]+Lpos-Lef;    }    Build(Lef,Mid,dep+1);    Build(Mid+1,Rig,dep+1);}int Query(int Lef,int Rig,int l,int r,int dep,int K){    if(l==r) return Tree[dep][l];    int Mid = (Lef+Rig)>>1;    int Cnt = Toleft[dep][r] - Toleft[dep][l-1];    if(Cnt>=K)    {        int newL = Lef + Toleft[dep][l-1] - Toleft[dep][Lef-1];        int newR = newL + Cnt -1;        return Query(Lef,Mid,newL,newR,dep+1,K);    }    else    {        int newR = r + Toleft[dep][Rig] - Toleft[dep][r];        int newL = newR - (r-l-Cnt);        return Query(Mid+1,Rig,newL,newR,dep+1,K-Cnt);    }}int main(){//    freopen("F:\\test.txt","r",stdin);//    freopen("F:\\tsst.txt","w",stdout);    int N,M;    while(~scanf("%d %d",&N,&M))    {        for(int i=1;i<=N;i++)        {            scanf("%d",&Tree[0][i]);            Sorted[i]=Tree[0][i];        }        sort(Sorted+1,Sorted+N+1);        Build(1,N,0);        for(int i=1;i<=M;i++)        {            int a,b,K;            scanf("%d %d %d",&a,&b,&K);            printf("%d\n",Query(1,N,a,b,0,K));        }    }}
0 0
原创粉丝点击