首页 > 代码库 > HDU 2665(主席树,无修改第k小)

HDU 2665(主席树,无修改第k小)

                                Kth number

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

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
Source
HDU男生专场公开赛——赶在女生之前先过节(From WHU)
垃圾主席树  浪费我时间
 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cctype> 5 #include<cmath> 6 #include<cstring> 7 #include<map> 8 #include<stack> 9 #include<set>10 #include<vector>11 #include<algorithm>12 #include<string.h>13 #define ll long long14 #define LL unsigned long long15 using namespace std;16 const int INF=0x3f3f3f3f;17 const double eps=0.0000000001;18 const int N=100000+10;19 struct node{20     int left,right;21     int val;22 }tree[N*40];23 int cnt;24 int a[N],b[N];25 int root[N];26 int build(int l,int r){27     int pos=++cnt;28     tree[pos].val=0;29     if(l==r)return pos;30     int mid=(l+r)>>1;31     tree[pos].left=build(l,mid);32     tree[pos].right=build(mid+1,r);33     return pos;34 }35 void update(int pre,int &now,int x,int l,int r){36     tree[++cnt]=tree[pre];37     now=cnt;38     tree[now].val++;39     if(l==r)return;40     int mid=(l+r)>>1;41     if(x<=mid){42         update(tree[pre].left,tree[now].left,x,l,mid);43     }44     else{45         update(tree[pre].right,tree[now].right,x,mid+1,r);46     }47 48 }49 int query(int L,int R,int k,int l,int r){50     if(l==r) return l;51     int mid=(l+r)>>1;52     int sum=tree[tree[R].left].val-tree[tree[L].left].val;53     if(k<=sum){54         return query(tree[L].left,tree[R].left,k,l,mid);55     }56     else{57         return query(tree[L].right,tree[R].right,k-sum,mid+1,r);58     }59 60 }61 int main()62 {63     int t;64     scanf("%d",&t);65     while(t--){66         memset(root,0,sizeof(root));67         memset(a,0,sizeof(a));68         memset(b,0,sizeof(b));69         int n,m;70         scanf("%d%d",&n,&m);71         cnt=0;72         for(int i=1;i<=n;i++) {73             scanf("%d",&a[i]);74             b[i]=a[i];75         }76         sort(b+1,b+1+n);77         int tt = unique(b+1,b+1+n)-b-1;78         for(int i=1;i<=n;i++) {79             a[i]=lower_bound(b+1,b+1+tt,a[i])-b;//二分找到a[i]的位置81             update(root[i-1],root[i],a[i],1,tt);//root[i-1]表示上一个版本的线段树82         }83         for(int i=1;i<=m;i++) {84             int l,r,k;85             scanf("%d%d%d",&l,&r,&k);86             int ans=query(root[l-1],root[r],k,1,tt); //ans是第k个数的位置87             printf("%d\n", b[ans]);//因为询问的是哪个数,所以要b[ans]88         }89     }90     return 0;91 }

 

HDU 2665(主席树,无修改第k小)