[学习笔记]CDQ分治
分治,考虑前一半对后一半的影响。
(和一般分治不太相同的思想是,一般分治不分谁对谁的影响,跨mid的都要统计。(全局变量统计)
而CDQ貌似要落脚到前一半对后一半的影响上,也就是贡献在后一半统计,由前一半产生。
)
大概使用情况:
1.三维偏序
2.优化DP
3.???
例题
[学习笔记]多维偏序
这个里面有。
注意处理三维情况的巧妙性。
[HEOI2016/TJOI2016]序列
CDQ三维偏序优化DP
(树套树也没问题)
注意的是,先divi(l,mid)再统计(l,r)再递归divi(mid+1,r)
因为必须统计贡献有先后了。否则显然有后效性。。
[BOI2007]Mokia 摩基亚
矩阵查询,前缀差分。
然后cdq分治,两边按照x排序一下,然后双指针扫描,左半部分的修改,加入权值线段树(权值树状数组)里,然后区间查询统计增加的用户即可。
可以离散化节省时空。
#include<bits/stdc++.h> #define reg register int #define il inline #define mid ((l+r)>>1) #define numb (ch^'0') using namespace std; typedef long long ll; il void rd(int &x){char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x); } namespace Miracle{ const int N=200000+5; struct node{int sum; }t[4*N]; struct que{int x,y0,y1;int typ;int sum;int id;bool friend operator<(que a,que b){return a.x<b.x;} }q[N]; int tot; struct matrix{int ans; }a[10000+5]; int cnt; int b[N],c[N],num; int mx; void pushup(int x){t[x].sum=t[x<<1].sum+t[x<<1|1].sum; } void add(int x,int l,int r,int to,int c){if(l==r){t[x].sum+=c;return;}if(to<=mid) add(x<<1,l,mid,to,c);else add(x<<1|1,mid+1,r,to,c);pushup(x); } int query(int x,int l,int r,int L,int R){if(L<=l&&r<=R){return t[x].sum;}int ret=0;if(L<=mid) ret+=query(x<<1,l,mid,L,R);if(mid<R) ret+=query(x<<1|1,mid+1,r,L,R);return ret; } void divi(int l,int r){if(l==r) return;divi(l,mid);divi(mid+1,r);//cout<<" l "<<l<<" r "<<r<<endl;sort(q+l,q+mid+1);sort(q+mid+1,q+r+1);int j=l;for(reg i=mid+1;i<=r;++i){if(q[i].typ==1) continue;while(j<=mid&&(q[j].x<=q[i].x)){if(q[j].typ!=1) {++j;continue;}add(1,1,num,q[j].y0,q[j].sum);++j;}q[i].sum+=query(1,1,num,q[i].y0,q[i].y1);}for(reg i=l;i<j;++i){if(q[i].typ!=1) continue;add(1,1,num,q[i].y0,-q[i].sum);} // for(reg i=1;i<=tot;++i){ // cout<<i<<" : "<<q[i].typ<<" "<<q[i].x<<" "<<q[i].sum<<endl; // } // cout<<"sum "<<t[1].sum<<endl; } int main(){int op;int x0,x1,y0,y1;while(1){scanf("%d",&op);if(op==3) break;else if(op==0){scanf("%d",&mx);}else if(op==1){++tot;q[tot].typ=1;scanf("%d%d%d",&q[tot].x,&q[tot].y0,&q[tot].sum);b[++num]=q[tot].y0;}else{++cnt;++tot;q[tot].typ=2;q[tot].id=cnt;scanf("%d%d%d%d",&x0,&y0,&x1,&y1);q[tot].x=x1,q[tot].y0=y0,q[tot].y1=y1;b[++num]=q[tot].y0;b[++num]=q[tot].y1;++tot;q[tot].typ=3;q[tot].id=cnt;q[tot].x=x0-1,q[tot].y0=y0,q[tot].y1=y1;}}sort(b+1,b+num+1);num=unique(b+1,b+num+1)-b-1;//cout<<" tot "<<tot<<endl;for(reg i=1;i<=tot;++i){//cout<<" ii "<<i<<" ";if(q[i].typ==1){q[i].y0=lower_bound(b+1,b+num+1,q[i].y0)-b;//cout<<" typ"<<q[i].typ<<" "<<q[i].y0<<endl; }else{q[i].y0=lower_bound(b+1,b+num+1,q[i].y0)-b;q[i].y1=lower_bound(b+1,b+num+1,q[i].y1)-b;//cout<<" typ"<<q[i].typ<<" "<<q[i].y0<<" "<<q[i].y1<<endl; }}divi(1,tot);for(reg i=1;i<=tot;++i){if(q[i].typ==2){a[q[i].id].ans+=q[i].sum;}else if(q[i].typ==3){a[q[i].id].ans-=q[i].sum;}}for(reg i=1;i<=cnt;++i){printf("%d\n",a[i].ans);}return 0; }} int main(){Miracle::main();return 0; }/*Author: *Miracle*Date: 2018/11/23 21:10:32 */
Mokia 摩基亚
转载于:https://www.cnblogs.com/Miracevin/p/10009615.html
[学习笔记]CDQ分治相关推荐
- 学习笔记——CDQ分治
再次感谢这位大佬的博客:https://www.cnblogs.com/ljc20020730/p/10395866.html CDQ分治,是一种在分治合并中计算前面值对后面答案的贡献的一种算法.今天 ...
- [学习笔记] CDQ分治 从感性理解到彻底晕菜
==== €€£ WARNING ==== 这篇博文由于过于久远并没有什么干货已被废弃 新博文链接->CDQ分治&整体二分 ==== = ...
- 【学习笔记】分治FFT
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 分治FFT 1. Luogu P4721 [模板]分治 FFT 2. 2020 ICPC Mac ...
- 算法笔记-CDQ分治
CDQ分治 多用于解决多维偏序问题,通过增加 l o g ( n ) log(n) log(n) 的时间将偏序问题降一维.离线算法 对于修改和询问问题,修改操作的位置小于某一询问时,修改才会对询问产生 ...
- 【转】算法导论学习笔记 一 分治算法
分治策略是一种常见的算法.在分治策略中,我们递归的求解一个问题,在每层递归中应用如下三个步骤: 1. 分解,将问题分解成规模更小但解决方案相同的子问题 2. 解决,递归的求解子问题,如果子问题足够小则 ...
- 【cdq分治】cdq分治与整体二分学习笔记Part2.cdq分治
上午的学习学会了整体二分,下午学了cdq分治 发现了二者的区别: 整体二分的主体是在不断地二分答案(把所有询问二分),而cdq分治则是在不断地二分操作. 当然同样的,cdq分治的复杂度也是与区间长度正 ...
- 【cdq分治】cdq分治与整体二分学习笔记Part1.整体二分
之所以把cdq分治和整体二分放在一起学习,是因为他们两个实在太像了-不管是做法还是代码- 感觉整体二分可能会比cdq分治稍微简单那么一点点?所以先学整体二分. 整体二分是对答案进行二分,其具体操作如下 ...
- 【教程】简易CDQ分治教程学习笔记
前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦! CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...
- [摸鱼]cdq分治 学习笔记
待我玩会游戏整理下思绪(分明是想摸鱼 cdq分治是一种用于降维和处理对不同子区间有贡献的离线分治算法 对于常见的操作查询题目而言,时间总是有序的,而cdq分治则是耗费\(O(logq)\)的代价使动态 ...
最新文章
- 委员建议开辟多种科研资助模式,呼唤“科研悬赏制”
- oracler日期函数相差六个月_Oracle数据库之SQL单行函数---日期函数集锦
- go语言中的引用类型
- ubuntu怎么清空回收站?(权限不够)
- wordpress 新建php文件大小,WordPress最大上传文件大小限制修改
- dg oracle 切换模式_谈谈dg切换涉及的概念:switchover和failover区别
- ehcache 一二事 - ssm 中ehcashe的简单配置应用
- VMware虚拟机Centos7配置双网卡双IP踩坑
- 均匀带电直线外一点的场强
- 数字电子技术基础笔记(精简)
- Python3.6 word批量转换为txt提取
- 2014传智播客ios第4期基础班+就业班
- 定义一个函数,返回整形数组中最大值
- 后门攻击阅读笔记,Input-aware dynamic backdoor attack
- 台式计算机不同处理器型号,买电脑不要再被坑了,CPU型号解读
- Postman请求报405错误
- Scratch节假日主题课:植树节种五棵树
- 美国国土安全部仍然使用 COBOL 语言
- 华三,思科ACL命令解析
- 使用 Webmin+bind9快速搭建私有DNS服务器
热门文章
- modernizr 支持html5,使用modernizr.js检测浏览器对html5以及css3的支持情况
- python opencv imread()函数,关于:灰度图(二维数组图),彩色图(三维数组图)
- 【MySQL】(图解)快速理解内连接、外连接、左连接、右连接
- 【建站系列教程】2.2、fiddler手机抓包教程
- numpy中的cov(方差计算)简单介绍
- LetCode 70. Climbing Stairs--动态规划-爬梯子--递归等解法
- 联想输入快捷键_UG软件F8快捷键和笔记本电脑F8快捷键冲突的解决方法
- 鸿蒙电视哔哩哔哩,[4K视频] 65寸智能电视只要3299元?荣耀智慧屏X1开箱
- c语言const与*位置关系,C语言程序的存储区域与const关键字的使用方法
- Swift如何使用Masonry和SnapKit