首页 > 其他分享 >【学习笔记】【自学】三维偏序 (CDQ)

【学习笔记】【自学】三维偏序 (CDQ)

时间:2023-09-10 21:12:04浏览次数:33  
标签:偏序 right mid same leq CDQ 数组 自学 left

[P3810 【模板】三维偏序(陌上花开)](https://www.luogu.com.cn/problem/P3810)

题目描述:有 $ n $ 个元素,第 $ i $ 个元素有 $ a_i,b_i,c_i $ 三个属性,设 $ f(i) $ 表示满足 $ a_j \leq a_i $ 且 $ b_j \leq b_i $ 且 $ c_j \leq c_i $ 且 $ j \ne i $ 的 $j$ 的数量。
对于 $ d \in [0, n) $,求 $ f(i) = d $ 的数量。

首先,这是一个三维偏序,我们一维一维的来思考。

第一维用 $\text{sort}$ 按 $a_i.x$ 从小到大排序,保证第一维 $a_i$ 有序。注意,题目中说是满足 $ a_j \leq a_i $ 且 $ b_j \leq b_i $ 且 $ c_j \leq c_i $,即若有重复的,则需要判重,且我们有需要求出每一个三元组 $(a_{i}.x,a_{i}.y,a_{i}.z)$它出现的次数,在后期才能进行计算,简单起见,在这里我们将三元组 $(a_{i}.x,a_{i}.y,a_{i}.z)$它出现的次数设为 $t_i$,设 $a_i$ 为去重后的数组,$n$ 为去重后的数组长度。


第二维&第三维: 用一个类似归并排序的 $\text{CDQ}$ 分治,即对于一个$\text{CDQ}(left,right)$:

若 $left=right$,则直接 $return$,此时为边界条件。

接着,递归 $\text{CDQ}(left,mid),\text{CDQ}(mid+1,right)$,把 $[left,right]$ 这个区间分成 $[left,mid]$ 和 $[mid+1,right]$。

然后,归并排序,将 $[left,mid]$ 和 $[mid+1,right]$ 这两个有序的数组合并。

设 $left_1$ 为区间 $[left,mid]$ 的左指针,$right_1$ 为区间 $[left,mid]$ 的右指针,$left_2$ 为区间 $[mid+1,right]$ 的左指针,$right_2$ 为区间 $[mid+1,right]$ 的右指针。

则当 $a_{left_1}.y \le a_{left_2}.y$ 时,又因之前按照 $a_i.x$ 排过序,即也满足 $a_{left_1}.x \le a_{left_2}.x$,即满足了题目中的要求 $a_j\le a_i$,$b_j\le b_i$,此时将树状数组中的 $a_{left_1}.z$的位置上加上 $t_i$,即有 $t_{left_1}$ 个三元组 $(a_{left_1}.x,a_{left_1}.y,a_{left_1}.z)$,即树状数组中的 $add(a_{left_1}.z,t_{left_1})$,这就是第三维,再将 $a_{left_1}$ 放入临时数组 $tmp$ 中,注意,不用在意树状数组中的求和过程,因为这样可能会阻碍你对此题的理解。

当 $a_{left_1}.y \ge a_{left_2}.y$ 时,既不满足题目的要求 $a_j\le a_i$,$b_j\le b_i$,不能放入树状数组中,否则不合题意,则将 $a_{left_2}.ans$ 加上 $\sum\limits_{i=1}^{a_{left_2}.z}f_i$,即树状数组中的 $sum(a_{left_2}.z)$,这也是第三维,再将 $a_{left_2}$ 放入临时数组 $tmp$ 中。

接着,区间 $[left,mid]$ 和 $[mid+1,right]$ 中剩余元素也是通过同样的方法。

将刚才加上的所有 $t_{i\in[l,mid]}$复原,在树状数组中即为 $\text{add}(i,t_i)$。

最后,将临时数组 $tmp$ 中的变量在赋值给 $a$,这样就完成了一次 $\text{CDQ}(left,right)$。

注意,在进行 $\text{CDQ}(1,n)$ 后,需要统计 $f(i)=d\in[0,n)$ 的数量。

用 $print_i$ 表示,则 $print_{a_i.ans+a_i.same-1}=a_i.same$ 表示 $a_i.ans+a_i.same-1$ 出现的次数加上 $a_i.same$,其中 $a_i.ans+a_i.same-1$ 表示对于 $a_i$ 的答案,因为 $a_i$ 出现的次数为 $a_i.same$,题目中求 $ a_j \leq a_i $ 且 $ b_j \leq b_i $ 且 $ c_j \leq c_i $,即那 $a_i.same$ 个 $a_i$ 也满足要求,即 $a_i$ 和其他 $a_i.same-1$ 个 $a_i$ 配对,即加上 $a_i.same-1$,其余 $a_i.same-1$ 个 $a_i$ 也同样,即答案都为 $a_i.ans+a_i.same-1$,就是 $print_{a_i.ans+a_i.same-1}=a_i.same$。

标签:偏序,right,mid,same,leq,CDQ,数组,自学,left
From: https://www.cnblogs.com/CSP-AK-zyz/p/17691928.html

相关文章

  • Java自学网站推荐--全网最靠谱
    简介网上有各种Java学习网站,本文推荐的这个Java网站全网最靠谱,质量远超其他所有网站。这个网站是:自学精灵,这是全网最强的Java学习网站,可以直接百度搜索自学精灵,或者访问:自学精灵-IT技术星球。我不喜欢“全网最强”这样的字眼,但本站的内容确实是全网最强!(大家可以多找几个Java网站......
  • Java自学网站推荐--全网最靠谱
    ​简介网上有各种Java学习网站,本文推荐的这个Java网站全网最靠谱,质量远超其他所有网站。这个网站是:自学精灵,这是全网最强的Java学习网站,可以直接百度搜索自学精灵,或者访问:自学精灵-IT技术星球。​我不喜欢“全网最强”这样的字眼,但本站的内容确实是全网最强!(大家可以多找几个......
  • 自学CSday1
    初识c语言1:写c代码时,新建项目(设置好自己代码的存放点);添加源文件c代码中,.c--源文件  .h--头文件(head,就是放在最头部):写c语言时,文件名称命名为test.c2:main--主函数-程序的入口与//不可以没有,在一串代码中有且只有一个3:return0;-返回0(此处0为整型)4:int-整型intmain中,main前面的int......
  • Pt.I 从零基础到音乐制作者的自学指南
    1音符1.14/8/16分音符4分音符代表一个节拍的时值,在4/4拍子中,4分音符就是一个拍.如果在速度为60BPM的情况下演奏4分音符,每个4分音符会持续1秒.8分音符是4分音符时值的一半,16分音符是8分音符的一半.1.2连音当两个或多个相同的音符连在一起时,......
  • S2 二,三维偏序
    二维偏序Q:给定N个有序对\((a,b)\),求对于每个\((a,b)\),满足\(a_0<a\)且\(b_0<b\)的有序对\((a_0,b_0)\)有多少个经典的逆序对问题,可以考虑用树状数组解决,先按照第一维排序,然后离散化在第一维已经处理的情况下去边处理第二维边记录。1.CF1311FMovingPoints不难......
  • 【学习笔记】二维偏序
    看着名字挺高级的就来学一下awa二维偏序是解决这样子的问题:有\(n\)个点,每一个点都有两个属性\(a,b\),且满足\[\left\{\begin{aligned}&i<j\\&a_i\lea_j\\&b_i\leb_j\end{aligned}\right.\]然后去求一些奇奇怪怪的问题解法是离散化后排序然后用两个树状数组来维护......
  • 华为认证 | 自学HCIE,难度有多大?
    华为认证HCIE(HuaweiCertifiedInternetworkExpert)是华为网络技术领域的认证之一,难度较大。考生需要通过一系列考试,包括笔试、实验考试,全面检测其网络技术理论知识方面的能力和应用能力。那么,HCIE的难度有多大?自学能否考过呢?本文将从这两个方面进行解答。01HCIE的难度有多大★专......
  • CDQ 分治
    定义CDQ分治作为一种思想,主要在解决形如\([l,r]\)区间中找符合要求的点对\((i,j)\)的问题时应用。具体的思想是:先递归解决\([l,mid]\)和\([mid+1,r]\)中的点对;再计算\(l\lei\lemid<mid+1\lej\ler\)的点对\((i,j)\)数量。例题例1:P3810【模板】三维偏序(陌......
  • CDQ分治
    如果现在有一些操作,有些操作会产生贡献,同时里面的情况会依次发生更改,要求我们去维护发生更改后的总贡献。这个问题会使得我们初感很棘手,主要原因在于这是一个动态的问题,当其中一个操作发生变化后会对很多的操作产生影响,导致寻常的数据结构难以维护。而现在引入的CDQ分治可以将一......
  • SQL之母_sql自学网站例题
    http://sqlmother.yupi.icu/感觉还是直接写题对我有效果些虽然我有点容易知难而退。请编写一条SQL查询语句,从名为student的数据表中选择出所有学生的姓名(name)和分数(score),并且额外计算出分数的2倍(double_score)。点击查看代码selectname,score,score*2asdouble_scoref......