[学习笔记] CDQ分治 从感性理解到彻底晕菜
==== €€£ WARNING ====
这篇博文由于过于久远并没有什么干货已被废弃
新博文链接->CDQ分治&整体二分
==== ====
最近学了一种叫做CDQ分治的东西...用于离线处理一系列操作与查询似乎跑得很快233
CDQ的名称似乎源于金牌选手陈丹琦
概述:
对于一坨操作和询问,分成两半,单独处理左半边和处理左半边对于右半边的影响,就叫$CDQ$分治。
乍一看似乎不算难理解...?
这"一坨操作和询问"是要求靠左的操作可以影响所有右侧操作,靠右的查询的值依赖于左侧的操作...
内部实现:
将左右区间按一定规律排序后分开处理,递归到底时直接计算答案,对于一个区间,按照第二关键字split成两个区间,先处理左区间,之后因为整个区间是有序的,就可以根据左区间来推算右区间的答案,最后递归处理右区间即可。归纳起来就是
1. 区间按第一关键字分成两半
2. 计算左区间对右区间的贡献
3. 撤销修改
4. 按第二关键字拆成两半并排序
5. 递归下去继续处理
这种时候常常只能选择参考代码感性理解一下(雾)
对于上面的例题($Mokia$)来说,我们先将一个查询操作差分为$4$个前缀和分别计算,然后将所有操作按$x$值为第一关键字,$y$为第二关键字排序(保证左边的操作可以影响右边操作),然后按照时间戳分开重新排序为两个序列并分开递归下去求值QwQ
直接拿这个板子题的实现细节举个栗子好了QwQ
我们拿$CDQ$函数来说一下...
void CDQ(int l,int r){
if(l==r)
return;
int mid=(l+r)>>;
int ll=l;
int lr=mid+;
for(int i=l;i<=r;i++){
if(query[i].ID<=mid&&query[i].operation==)
Add(query[i].y,query[i].value);
if(query[i].ID>mid&&query[i].operation==)
ans[query[i].position]+=query[i].value*Query(query[i].y);
}
for(int i=l;i<=r;i++){
if(query[i].ID<=mid&&query[i].operation==)
Add(query[i].y,-query[i].value);
}
for(int i=l;i<=r;i++){
if(query[i].ID<=mid)
tmp[ll++]=query[i];
else
tmp[lr++]=query[i];
}
for(int i=l;i<=r;i++)
query[i]=tmp[i];
CDQ(l,mid);
CDQ(mid+,r);
}
$2\text{~}6$行没啥可讲的(吧)
然后我们从$l$到$r$进行遍历.因为我们按$x$和$y$排序了所以更改肯定在它所影响的查询操作的值计算之前进行($7\text{~}12$行)
接着我们撤销修改,因为递归下去后这些值会失效所以要清空($13\text{~}16$行)
然后我们按照时间戳分别分为左右两部分($17\text{~}24$行)
最后递归下去处理.
仔细分析我们可以发现这个过程刚好做到了"不重不漏":不重复计算查询涉及到的修改操作的贡献;不漏掉修改操作对后面查询的贡献.
然后摘一句总结
CDQ分治主要用于处理能够离线的低维偏序(3维及以下),3维偏序常态是套BIT,一般对于x排序,然后对于id进行cdq分治,对于y用BIT来维护即可。
据说更高维的偏序也可以处理但是好像需要一些特殊方法?
(然后又草率地结束了)
(我好菜啊QwQ)
(放图跑)

[学习笔记] CDQ分治 从感性理解到彻底晕菜的更多相关文章
- 学习笔记 | CDQ分治
目录 前言 啥是CDQ啊(它的基本思想) 例题 后记 参考博文 前言 博主太菜了 学习快一年的OI了 好像没有什么会的算法 更寒碜的是 学一样还不精一样TAT 如有什么错误请各位路过的大佬指出啊感谢! ...
- [学习笔记] CDQ分治&整体二分
突然诈尸.png 这两个东西好像都是离线骗分大法... 不过其实这两个东西并不是一样的... 虽然代码长得比较像 CDQ分治 基本思想 其实CDQ分治的基本思想挺简单的... 大概思路就是长这样的: ...
- [学习笔记]CDQ分治和整体二分
序言 \(CDQ\) 分治和整体二分都是基于分治的思想,把复杂的问题拆分成许多可以简单求的解子问题.但是这两种算法必须离线处理,不能解决一些强制在线的题目.不过如果题目允许离线的话,这两种算法能把在线 ...
- 学习笔记——CDQ分治
再次感谢这位大佬的博客:https://www.cnblogs.com/ljc20020730/p/10395866.html CDQ分治,是一种在分治合并中计算前面值对后面答案的贡献的一种算法.今天 ...
- go 学习笔记之10 分钟简要理解 go 语言闭包技术
闭包是主流编程语言中的一种通用技术,常常和函数式编程进行强强联合,本文主要是介绍 Go 语言中什么是闭包以及怎么理解闭包. 如果读者对于 Go 语言的闭包还不是特别清楚的话,可以参考上一篇文章 go ...
- LDA主题模型学习笔记5:C源代码理解
1.说明 本文对LDA原始论文的作者所提供的C代码中LDA的主要逻辑部分做凝视,原代码可在这里下载到:https://github.com/Blei-Lab/lda-c 这份代码实现论文<Lat ...
- 算法笔记--CDQ分治 && 整体二分
参考:https://www.luogu.org/blog/Owencodeisking/post-xue-xi-bi-ji-cdq-fen-zhi-hu-zheng-ti-er-fen 前置技能:树 ...
- go lang学习笔记——channel机理及调度理解
<Go语言编程>一书介绍了libtask库,可以认为这个库等同于go的底层goroutine实现. libtask库的channel的数据结构如下: struct Alt { Channe ...
- 【DirectX 11学习笔记】世界矩阵的理解-运动合成
最近在看龙书,写一下自己的学习理解,主要是物体运动的合成. 物体于局部坐标系内构建,每个物体拥有自己的局部坐标系以及相应的顶点矩阵A,并通过世界矩阵变换到唯一的世界坐标系. 物体在某时刻发生了位移和旋 ...
随机推荐
- js数组及数组应用(冒泡和二分,遍历输出)
一.定义:1)var arr=new Array(); 加数据:arr[0]=1; 2)定义同时赋值:var arr=new Array(1,2,3,4,5); 3)调用:var arr=new Ar ...
- 2017最新xcode打包APP详细图文
网上的xcode打包ipa教程大多太旧而且又不完整,所以整理了一个最新的完整详细的xcode打包APP的图文教程分享给小白到大神路上前进的你我. xcode打包IPA包之前先申请iOS证书,然后导入证 ...
- oracle sql语句跟踪及性能分析工具实现
在网上找了一大圈,没找着合适的工具来跟踪oracle一段时间的sql. 我们的场景是打算自动化跑遍所有场景(rft)+fiddler跟踪请求+后端跟踪sql,根据结果去分析慢的请求和sql,本来awr ...
- windbg工具安装配置及dump抓取
安装与配置windbg 安装与配置windbg的symbol(符号) 第一步 下载WinDBG, 第二步 双击下载的文件安装windbg.安装时注意记住安装到那里了. 第三步 windbg访问符号需要 ...
- PHP运行出现Notice : Use of undefined constant
这些是 PHP 的提示而非报错,PHP 本身不需要事先声明变量即可直接使用,但是对未声明变量会有提示.一般作为正式的网站会把提示关掉的,甚至连错误信息也被关掉 关闭 PHP 提示的方法 搜索php.i ...
- 错误Fatal error: Call to undefined function mb_strlen()的解决办法
其实这个就是没有开启php_mbstring模块.Windows下只需要修改安装目录下的php.ini文件把extension=php_mbstring.dll前面的“#”号注释符去掉保存后重启Apa ...
- 容器间通信的三种方式 - 每天5分钟玩转 Docker 容器技术(35)
容器之间可通过 IP,Docker DNS Server 或 joined 容器三种方式通信. IP 通信 从上一节的例子可以得出这样一个结论:两个容器要能通信,必须要有属于同一个网络的网卡. 满足这 ...
- python中的字符串编码
获取字符串的编码类型: encodingdate = chardet.detect(str) chardet用于实现字符串的编码类型检测 chardet的下载地址:https://pypi.pytho ...
- JAVA基础——面向对象三大特性:封装、继承、多态
JAVA面向对象三大特性详解 一.封装 1.概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问. 2.好处: 只能通过规定的方法访问数据. ...
- vmware虚拟机的克隆
开发中需要用到多个虚拟机进行实验.重新安装过程又太繁琐,通过vmware虚拟机自带软件能够很好的快速克隆出完全相同的系统.下面会为大家讲解关于vmware虚拟机怎么克隆,我所用的VMware版本是11 ...