zoukankan      html  css  js  c++  java
  • 划分树简单介绍

    我感觉划分树的基本思想是二分和归并排序,分为建树和查询两个部分。

    1、建树

      递归建树,以中值为界,将序列划分成左右两部分,直到分到每个点为止。同时,在建树的过程中,记录下每一层进入左区间的数的个数,方便查询时使用。

      注意:保持左右区间中数的相对顺序。

    (1)、中值唯一的情况。将小于等于中值的数放到左区间即可。

    (2)、中值不唯一的情况。为了防止左区间放了过多的和中值相等的数,导致小于中值的数放不进去,需要先统计小于中值的数有多少个,然后用等于中值的数来补全左区间剩余的位置。

        因此需要一个变量来标记一下可放中值数的个数。

    2、查询

      递归查询,判断查询 区间中有多少个进入左区间的数,如果K大于该数,说明所查的数在右区间,否则在左区间。因为该层下一层中左区间的数不全是由所查询区间得出的,还有一部分来自于所查询区间的左侧区间,所以在

    进入下一层查询时,应当避开这些无关的数,右区间亦然。

    具体细节见代码解释:(以 POJ 2104为例)

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<queue>
      7 #include<stack>
      8 #include<deque>
      9 #include<map>
     10 #include<iostream>
     11 using namespace std;
     12 typedef long long  LL;
     13 const double pi=acos(-1.0);
     14 const double e=exp(1);
     15 const int N = 100010;
     16 
     17 #define lson i << 1,l,m
     18 #define rson i << 1 | 1,m + 1,r
     19 
     20 int order[N],tree[20][N];
     21 int lgo[20][N];
     22 int ans=0,n;
     23 
     24 bool cmp(int a,int b)
     25 {
     26     return a<b;
     27 }
     28 
     29 void build(int ceng,int l,int r)
     30 {
     31 
     32     if(l==r)
     33         return ;
     34 
     35     int i,p,j;
     36     int le,ri,flag=0,mid;      //flag存储该进入左区间的中值的个数
     37     mid=(l+r) >> 1;
     38 
     39     flag=mid-l+1;                       //改的地方  左区间所能存的数的个数
     40     for(i=l;i<=r;i++)
     41         if(tree[ceng][i]<order[mid])    //改的地方  左区间中应存有的中值的个数
     42             flag--;
     43 
     44     le=l;
     45     ri=mid+1;
     46     for(i=l;i<=r;i++)
     47     {
     48         if(i==l)
     49             lgo[ceng][i]=0;
     50         else
     51             lgo[ceng][i]=lgo[ceng][i-1];    //记录有多少个数进入左区间
     52 
     53         if(tree[ceng][i]<order[mid]||(tree[ceng][i]==order[mid]&&flag>0))
     54         {
     55             tree[ceng+1][le++]=tree[ceng][i];
     56             lgo[ceng][i]++;
     57             if(tree[ceng][i]==order[mid])
     58                 flag--;
     59         }
     60         else
     61         {
     62             tree[ceng+1][ri++]=tree[ceng][i];
     63         }
     64     }
     65 
     66     build(ceng+1,l,mid);
     67     build(ceng+1,mid+1,r);
     68 }
     69 
     70 void query(int l,int r,int ql,int qr,int ceng,int k)
     71 {
     72 
     73     if(l==r)
     74     {
     75         ans=tree[ceng][l];
     76         return ;
     77     }
     78     int lgol,at_left,at_right,ingol;
     79 
     80     int mid=(l+r) >> 1;
     81 
     82     if(ql==l)
     83         lgol=0;
     84     else
     85         lgol=lgo[ceng][ql-1];       //改  查询区间的左侧区间进入左区间的个数
     86     ingol=lgo[ceng][qr]-lgol;       //改  查询区间进入左区间的个数
     87 
     88     if(k<=ingol)
     89     {
     90         at_left=l+lgol;      //有效的左起始位置
     91         query(l,mid,at_left,at_left+ingol-1,ceng+1,k);
     92     }
     93     else
     94     {
     95         at_left=mid+1+ql-l-lgol;    //有效的左起始位置
     96         query(mid+1,r,at_left,at_left+qr-ql+1-ingol-1,ceng+1,k-ingol);
     97     }
     98 }
     99 
    100 int main()
    101 {
    102     int i,p,j,k;
    103     int a,b,m;
    104     scanf("%d%d",&n,&m);
    105     for(i=1;i<=n;i++)
    106     {
    107         scanf("%d",&tree[0][i]);
    108         order[i]=tree[0][i];
    109     }
    110     sort(order+1,order+1+n,cmp);
    111     build(0,1,n);
    112     for(j=1;j<=m;j++)
    113     {
    114         ans=0;
    115         scanf("%d%d%d",&a,&b,&k);
    116         query(1,n,a,b,0,k);
    117         printf("%d
    ",ans);
    118     }
    119 
    120     return 0;
    121 
    122 }
  • 相关阅读:
    树洞留言板~
    异常The following attributes are mutually exclusive: asproute aspcontroller, aspaction asppage, asppagehandler
    持续交付:发布可靠软件的系统方法
    sql分页遍历出现重复数据原因与解决方案
    jenkens2权威指南
    timer
    window10、window11连接局域网共享打印机失败处理办法
    解决“Windows照片查看器无法显示此图片,因为计算机上的可用内存可能不足……”
    ts在项目中的使用三斜线引入 与 import区别
    vue unshift渲染遇到的坑
  • 原文地址:https://www.cnblogs.com/daybreaking/p/9448926.html
Copyright © 2011-2022 走看看