zoukankan      html  css  js  c++  java
  • hdu-2665 Kth number(划分树)

    题目链接:

    Kth number

    Time Limit: 15000/5000 MS (Java/Others)   

     Memory Limit: 32768/32768 K (Java/Others)



    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
     
    题意:
     
    给一个数列,问区间[l,r]内的第k大的数;
     
     
    思路:
     
    划分树的模板题;据说可以用可持久化线段树做,就是那个好难理解(看别人博客说创造可持久化线段树的居然说划分树好难理解,然后自己yy了可持久化线段树,简直丧心病狂),所以我就先学的划分树,划分树的思想跟快速排序很相似,用一个二维数组进行快速排序,另外的一个二维数组记录在排序的过程中有多少个数排在了左边,查找的时候就可以利用这个二维数组进行,真的是好神奇;
     
    AC代码:
     
    /*
    608MS 16072K 1761 B G++ 2014300227

    */
    #include <bits/stdc++.h> using namespace std; const int N=1e5+4; typedef long long ll; int n,m,a[N],sorted[N],k; int tree[32][N],num[32][N]; void build(int dep,int l,int r) { if(l>=r)return ; int mid=(l+r)>>1; int lp=l,rp=mid+1,sum=mid-l+1;//sum表示与sorted[mid]相等并且放在左边的个数;初始化为(r-l+1)/2,即左边的容量; for(int i=l;i<=r;i++) { if(tree[dep][i]<sorted[mid])sum--;//把放在左边的小于sorted[mid]的减去,剩下的就是==sorted[mid]的; } for(int i=l;i<=r;i++) { if(i!=l)num[dep][i]=num[dep][i-1]; else num[dep][i]=0; if(tree[dep][i]<sorted[mid]) { tree[dep+1][lp++]=tree[dep][i]; num[dep][i]++; } else if(tree[dep][i]==sorted[mid]&&sum>0) { tree[dep+1][lp++]=tree[dep][i]; num[dep][i]++; sum--; } else { tree[dep+1][rp++]=tree[dep][i]; } } build(dep+1,l,mid), build(dep+1,mid+1,r); } int query(int dep,int l,int r,int ql,int qr,int k) { if(l>=r)return tree[dep][l]; int mid=(l+r)>>1,s,ss; if(l!=ql) s=num[dep][ql-1],ss=num[dep][qr]-num[dep][ql-1];//s表示ql之前放在左边的个数,ss表示ql到qr这个区间内放在左边的个数; else s=0,ss=num[dep][qr]; if(k<=ss)return query(dep+1,l,mid,l+s,l+s+ss-1,k);//如果放在左边的个数就>=k,说明第k个数肯定在左边,右边就不用考虑了; else return query(dep+1,mid+1,r,mid+1+ql-l-s,mid+1+qr-l-s-ss,k-ss);//否则就在右边区间找第k个数; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); sorted[i]=tree[0][i]=a[i]; } sort(sorted+1,sorted+n+1); build(0,1,n); int l,r; for(int i=0;i<m;i++) { scanf("%d%d%d",&l,&r,&k); printf("%d ",query(0,1,n,l,r,k)); } } return 0; }
  • 相关阅读:
    jekins 实现Django项目的自动部署(ubuntu16.04,python2.7,django1.11)
    Ubuntu16.04 安装 Django
    小米笔记本 air 12.5寸 支持硬盘参数
    editplus5激活码
    jmeter UDV
    c语言 快速排序
    html禁止文本输入框记录输入记录,单击input出现输入过的记录
    python pstats ,profile 性能分析
    python profile性能分析
    python 获取本地语言和编码的代码
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5356641.html
Copyright © 2011-2022 走看看