zoukankan      html  css  js  c++  java
  • POJ 2104/TYVJ 1253 划分树模板

    求区间第k小值~

    详细注释见代码:

    View Code
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #define M 100005
     6 using namespace std;
     7 int sorted[M],toleft[30][M],tree[30][M],m,n;
     8 void read()
     9 {
    10     for(int i=1;i<=m;i++)
    11     {
    12         scanf("%d",&sorted[i]);
    13         tree[0][i]=sorted[i];
    14     }
    15     sort(sorted+1,sorted+1+m);
    16 }
    17 void create(int l,int r,int d)
    18 {
    19     if(l==r) return;
    20     int mid=(l+r)>>1;
    21     int same=mid-l+1;//左子树中的数字个数 
    22     for(int i=l;i<=r;i++)
    23         if(tree[d][i]<sorted[mid]) same--;//此时same成为和中位数相等的位于左子树的数字个数 
    24         
    25     int ls=l,rs=mid+1;//分别为左右区间的起点 
    26     for(int i=l;i<=r;i++)
    27     {
    28         int fg=0;
    29         if((tree[d][i]<sorted[mid])||(tree[d][i]==sorted[mid]&&same>0))//将符合条件的数分到左子树 
    30         {
    31             fg=1;
    32             tree[d+1][ls++]=tree[d][i];
    33             if(tree[d][i]==sorted[mid]) same--;//有些与中位数相同的数分到左子树,剩下的分到右子树 
    34         }
    35         else tree[d+1][rs++]=tree[d][i];//分到右子树 
    36         toleft[d][i]=toleft[d][i-1]+fg;//toleft[d][i]表示从l到i区间中有多少数分到了其左子树中 
    37     }
    38     //递归建树 
    39     create(l,mid,d+1);
    40     create(mid+1,r,d+1);
    41 }
    42 int query(int ql,int qr,int k,int l,int r,int d)
    43 {
    44     if(ql==qr) return tree[d][ql];
    45     int mid=(l+r)>>1;
    46     int x=toleft[d][ql-1]-toleft[d][l-1];//位于ql(待求区间左端点)(不包括ql)左边的放于左子树中的数字个数 
    47     int y=toleft[d][qr]-toleft[d][l-1];//位于qr(待求区间右端点)(包括qr)左边的放于左子树中的数字个数
    48     int ry=qr-l+1-y;//位于qr(包含qr)的在右子树中的数字个数 
    49     int cnt=y-x;//位于区间[ql,qr]中的在左子树中的数字个数 
    50     int rx=ql-l-x;//位于ql左边(不包含ql)的在右子树中的数字个数 
    51     if(cnt>=k) return query(l+x,l+y-1,k,l,mid,d+1);
    52     else return query(mid+rx+1,mid+ry,k-cnt,mid+1,r,d+1);
    53 }
    54 void go()
    55 {
    56     create(1,m,0);
    57     for(int i=1,a,b,k;i<=n;i++)
    58     {
    59         scanf("%d%d%d",&a,&b,&k);
    60         int ans=query(a,b,k,1,m,0);
    61         printf("%d\n",ans);
    62     }
    63 }
    64 int main()
    65 {
    66     while(scanf("%d%d",&m,&n)!=EOF)
    67     {
    68         read();
    69         go();
    70     }
    71     return 0;
    72 }
    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    Java绘出pdf实现方法
    Java设置字体颜色
    猜测分箱算法
    获取图片存储到本地
    input(file)异步上传文件
    物流轨迹抓取
    bootstrap 模态框
    从数组中随机选择一个数
    spring cron表达式
    mabtis批量修改
  • 原文地址:https://www.cnblogs.com/proverbs/p/2713548.html
Copyright © 2011-2022 走看看