关于划分树

断断续续看了几天。。。。事实证明这种东西一定要时间集中一点看,不然出活很慢。。。

看的时候主要是这么几个问题:

第一,为什么这样建树

第二,为什么这样查询,区间控制的理由是什么


先科普一下基本概念:(转)

划分树的定义

         划分树定义为,它的每一个节点保存区间[lft,rht]所有元素,元素顺序与原数组(输入)相同,但是,两个子树的元素为该节点所有元素排序后(rht-lft+1)/2个进入左子树,其余的到右子树,同时维护一个num域,num[i]表示lft->i这个点有多少个进入了左子树。


划分树包括两个部分,一个是每一层存放的数(排序不同)(val),一个是在每个数之前(包括它自己)进入左子树的个数(num)。

在得到一串数列之后,对其进行sort,之后每层树的比较,都是通过与相对区间中的中位数进行比较。通过这种方式,可以得到每个数相对的排序,比如说在第i层,在左子树内,有tree[i].val[j],tree[i].val[k],通过比较j,k的num值可以得到相对的大小关系。

定义:

constint N=1e5+5;
int sorted[N];            //对原来集合中的元素排序后的值
struct node
{
         int valu[N];       //val记录第k层当前位置元素的值
         int num[N];                //num记录元素所在区间的当前位置之前进入左孩子的个数
        
}t[20];     对于10万左右的数列是没问题的。(2^20)


建树:

</pre><pre style="font-family: 'Courier New';"><strong><span style="color:blue;">void</span></strong> create<strong><span style="color:#FF00FF;">(</span><span style="color:blue;">int</span></strong> l<strong><span style="color:#FF00FF;">,</span><span style="color:blue;">int</span></strong> r<strong><span style="color:#FF00FF;">,</span><span style="color:blue;">int</span></strong> rt<strong><span style="color:#FF00FF;">)
{</span></strong>
    num<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong><span style="color:#CC3300;">0</span><strong><span style="color:#FF00FF;">]=</span></strong><span style="color:#CC3300;">0</span><strong><span style="color:#FF00FF;">;</span><span style="color:#0000FF;">
    if</span><span style="color:#FF00FF;">(</span></strong>l<strong><span style="color:#FF00FF;">==</span></strong>r<strong><span style="color:#FF00FF;">)</span><span style="color:#0000FF;"> return</span><span style="color:#FF00FF;">;</span><span style="color:blue;">
    int</span></strong> mid<strong><span style="color:#FF00FF;">=(</span></strong>l<strong><span style="color:#FF00FF;">+</span></strong>r<strong><span style="color:#FF00FF;">)>></span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">;</span><span style="color:blue;">
    int</span></strong> ll<strong><span style="color:#FF00FF;">=</span></strong>l<strong><span style="color:#FF00FF;">,</span></strong>rr<strong><span style="color:#FF00FF;">=</span></strong>mid<strong><span style="color:#FF00FF;">+</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">;</span><span style="color:blue;">
    int</span></strong> same<strong><span style="color:#FF00FF;">=</span></strong>mid<strong><span style="color:#FF00FF;">-</span></strong>l<strong><span style="color:#FF00FF;">+</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">;</span><span style="color:blue;">

    int</span></strong> i<strong><span style="color:#FF00FF;">;</span><span style="color:#0000FF;">
    for</span><span style="color:#FF00FF;">(</span></strong>i<strong><span style="color:#FF00FF;">=</span></strong>l<strong><span style="color:#FF00FF;">;</span></strong>i<strong><span style="color:#FF00FF;"><=</span></strong>r<strong><span style="color:#FF00FF;">;</span></strong>i<strong><span style="color:#FF00FF;">++)</span><span style="color:#0000FF;"> if</span><span style="color:#FF00FF;">(</span></strong>val<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>i<strong><span style="color:#FF00FF;">]<</span></strong>sorted<strong><span style="color:#FF00FF;">[</span></strong>mid<strong><span style="color:#FF00FF;">])</span></strong> same<strong><span style="color:#FF00FF;">--;</span><span style="color:#0000FF;">
    for</span><span style="color:#FF00FF;">(</span></strong>i<strong><span style="color:#FF00FF;">=</span></strong>l<strong><span style="color:#FF00FF;">;</span></strong>i<strong><span style="color:#FF00FF;"><=</span></strong>r<strong><span style="color:#FF00FF;">;</span></strong>i<strong><span style="color:#FF00FF;">++)
    {</span><span style="color:#0000FF;">
        if</span><span style="color:#FF00FF;">(</span></strong>i<strong><span style="color:#FF00FF;">==</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">)</span></strong> num<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>i<strong><span style="color:#FF00FF;">]=</span></strong><span style="color:#CC3300;">0</span><strong><span style="color:#FF00FF;">;</span><span style="color:#0000FF;">
        else</span></strong> num<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>i<strong><span style="color:#FF00FF;">]=</span></strong>num<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>i<strong><span style="color:#FF00FF;">-</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">];</span><span style="color:#0000FF;">
        
        if</span><span style="color:#FF00FF;">(</span></strong>val<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>i<strong><span style="color:#FF00FF;">]<</span></strong>sorted<strong><span style="color:#FF00FF;">[</span></strong>mid<strong><span style="color:#FF00FF;">])
        {</span></strong>
            num<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>i<strong><span style="color:#FF00FF;">]++;</span></strong>
            val<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">+</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">][</span></strong>ll<strong><span style="color:#FF00FF;">++]=</span></strong>val<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>i<strong><span style="color:#FF00FF;">];
        }</span><span style="color:#0000FF;">
        else if</span><span style="color:#FF00FF;">(</span></strong>val<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>i<strong><span style="color:#FF00FF;">]></span></strong>sorted<strong><span style="color:#FF00FF;">[</span></strong>mid<strong><span style="color:#FF00FF;">])</span></strong> val<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">+</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">][</span></strong>rr<strong><span style="color:#FF00FF;">++]=</span></strong>val<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>i<strong><span style="color:#FF00FF;">];</span><span style="color:#0000FF;">
        else</span><span style="color:#FF00FF;">
        {</span><span style="color:#0000FF;">
            if</span><span style="color:#FF00FF;">(</span></strong>same<strong><span style="color:#FF00FF;">) {</span></strong>same<strong><span style="color:#FF00FF;">--;</span></strong>num<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>i<strong><span style="color:#FF00FF;">]++;</span></strong>val<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">+</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">][</span></strong>ll<strong><span style="color:#FF00FF;">++]=</span></strong>val<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>i<strong><span style="color:#FF00FF;">];}</span><span style="color:#0000FF;">
            else</span></strong> val<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">+</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">][</span></strong>rr<strong><span style="color:#FF00FF;">++]=</span></strong>val<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>i<strong><span style="color:#FF00FF;">];
        }
    }</span></strong>
        create<strong><span style="color:#FF00FF;">(</span></strong>l<strong><span style="color:#FF00FF;">,</span></strong>mid<strong><span style="color:#FF00FF;">,</span></strong>rt<strong><span style="color:#FF00FF;">+</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">);</span></strong>
        create<strong><span style="color:#FF00FF;">(</span></strong>mid<strong><span style="color:#FF00FF;">+</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">,</span></strong>r<strong><span style="color:#FF00FF;">,</span></strong>rt<strong><span style="color:#FF00FF;">+</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">);
}</span></strong>

查询:

<pre style="font-family: 'Courier New';"><strong><span style="color:blue;">int</span></strong> query<strong><span style="color:#FF00FF;">(</span><span style="color:blue;">int</span></strong> ll<strong><span style="color:#FF00FF;">,</span><span style="color:blue;">int</span></strong> rr<strong><span style="color:#FF00FF;">,</span><span style="color:blue;">int</span></strong> l<strong><span style="color:#FF00FF;">,</span><span style="color:blue;">int</span></strong> r<strong><span style="color:#FF00FF;">,</span><span style="color:blue;">int</span></strong> rt<strong><span style="color:#FF00FF;">,</span><span style="color:blue;">int</span></strong> k<strong><span style="color:#FF00FF;">) // ll,rr是目标区间
{</span><span style="color:#0000FF;">
    if</span><span style="color:#FF00FF;">(</span></strong>ll<strong><span style="color:#FF00FF;">==</span></strong>rr<strong><span style="color:#FF00FF;">)</span><span style="color:#0000FF;"> return</span></strong> val<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>ll<strong><span style="color:#FF00FF;">];</span><span style="color:blue;">
    int</span></strong> mid<strong><span style="color:#FF00FF;">=(</span></strong>l<strong><span style="color:#FF00FF;">+</span></strong>r<strong><span style="color:#FF00FF;">)>></span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">;</span><span style="color:blue;">
    int</span></strong> cnt<strong><span style="color:#FF00FF;">=</span></strong>num<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>rr<strong><span style="color:#FF00FF;">]-</span></strong>num<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>ll<strong><span style="color:#FF00FF;">-</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">];</span><span style="color:blue;">
    int</span></strong> newl<strong><span style="color:#FF00FF;">,</span></strong> newr<strong><span style="color:#FF00FF;">;</span><span style="color:#0000FF;">
    if</span><span style="color:#FF00FF;">(</span></strong>cnt<strong><span style="color:#FF00FF;">>=</span></strong>k<strong><span style="color:#FF00FF;">)
    {</span></strong>
        newl<strong><span style="color:#FF00FF;">=</span></strong>l<strong><span style="color:#FF00FF;">+</span></strong>num<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>ll<strong><span style="color:#FF00FF;">-</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">]-</span></strong>num<strong><span style="color:#FF00FF;">[</span></strong>rt<strong><span style="color:#FF00FF;">][</span></strong>l<strong><span style="color:#FF00FF;">-</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">];</span></strong>
        newr<strong><span style="color:#FF00FF;">=</span></strong>newl<strong><span style="color:#FF00FF;">+</span></strong>cnt<strong><span style="color:#FF00FF;">-</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">;</span><span style="color:#0000FF;">
        return</span></strong> query<strong><span style="color:#FF00FF;">(</span></strong>newl<strong><span style="color:#FF00FF;">,</span></strong>newr<strong><span style="color:#FF00FF;">,</span></strong>l<strong><span style="color:#FF00FF;">,</span></strong>mid<strong><span style="color:#FF00FF;">,</span></strong>rt<strong><span style="color:#FF00FF;">+</span></strong><span style="color:#CC3300;">1</span><strong><span style="color:#FF00FF;">,</span></strong>k<strong><span style="color:#FF00FF;">);  </span></strong>
//好吧。。再来一遍。。不知道别人看这个的时候会不会觉得很难理解。。但是像我这样的笨蛋。。。看查询的时候着实花了些功夫。知道怎么建树后看了这块代码很久不知道问什么这样。。。。。然后就问我自己,如果我这样建树了,那么在查询的时候,我要通过什么方式来缩小我查询的空间?为什么新的查询范围是这样的?
建树的时候应该意识到,对于每一层的i,他的坐标取决于在原序列中,他前面有几个mid小(大)的数插入到他前面了。所以,如果我们要往左子树上查找,我们要确定下一层的范围,那就是现在的l加上在[l,ll)前插入左子树的个数,就是下层中ll的值了,之后的同理。
    }
    else
    {
        newr=rr+num[rt][r]-num[rt][rr];
        newl=newr-(rr-ll-cnt);
        return query(newl,newr,mid+1,r,rt+1,k-cnt);
    }
    
}
 嗯。。代码是转的,。。。。 


看懂之后的感觉就是……这么简单的一个问题居然会想不明白!!傻逼!!!!QAQ。

其实应该是在建树的时候没有想明白过程,所以在查询的时候就更糊涂了。

在想问题的时候,不断问自己为什么是这样,感觉会促进大脑的……思考………………


*******************************************

拿了一道题练练手,结果发现之前看的代码有错!表示很生气! 划分树的资料不多,看知识介绍的时候代码只有那一份,每个贴代码的人为什么都没有仔细验证过。。。

表示看代码还是去搜模板比较好!恩!

然后,,,,刚开始一直RE,,,不知道为什么,但是建树的时候same的处理问题,坑了我一下午!!!然后,,,,在区间更新哪里的小细节还不能把握好,比如说加一减一 的问题……谁能教教我……………………

**************************************************

把上面的代码换成AC过的代码了。果然要自己敲一遍更好,不然都不知道自己有这么多的漏洞。

啊啊啊啊之前自己的想法都被del掉了QAQ、。。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值