分治,考虑前一半对后一半的影响。

(和一般分治不太相同的思想是,一般分治不分谁对谁的影响,跨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分治相关推荐

  1. 学习笔记——CDQ分治

    再次感谢这位大佬的博客:https://www.cnblogs.com/ljc20020730/p/10395866.html CDQ分治,是一种在分治合并中计算前面值对后面答案的贡献的一种算法.今天 ...

  2. [学习笔记] CDQ分治 从感性理解到彻底晕菜

    ==== €€£ WARNING ==== 这篇博文由于过于久远并没有什么干货已被废弃 新博文链接->CDQ分治&整体二分 ====                          = ...

  3. 【学习笔记】分治FFT

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 分治FFT 1. Luogu P4721 [模板]分治 FFT 2. 2020 ICPC Mac ...

  4. 算法笔记-CDQ分治

    CDQ分治 多用于解决多维偏序问题,通过增加 l o g ( n ) log(n) log(n) 的时间将偏序问题降一维.离线算法 对于修改和询问问题,修改操作的位置小于某一询问时,修改才会对询问产生 ...

  5. 【转】算法导论学习笔记 一 分治算法

    分治策略是一种常见的算法.在分治策略中,我们递归的求解一个问题,在每层递归中应用如下三个步骤: 1. 分解,将问题分解成规模更小但解决方案相同的子问题 2. 解决,递归的求解子问题,如果子问题足够小则 ...

  6. 【cdq分治】cdq分治与整体二分学习笔记Part2.cdq分治

    上午的学习学会了整体二分,下午学了cdq分治 发现了二者的区别: 整体二分的主体是在不断地二分答案(把所有询问二分),而cdq分治则是在不断地二分操作. 当然同样的,cdq分治的复杂度也是与区间长度正 ...

  7. 【cdq分治】cdq分治与整体二分学习笔记Part1.整体二分

    之所以把cdq分治和整体二分放在一起学习,是因为他们两个实在太像了-不管是做法还是代码- 感觉整体二分可能会比cdq分治稍微简单那么一点点?所以先学整体二分. 整体二分是对答案进行二分,其具体操作如下 ...

  8. 【教程】简易CDQ分治教程学习笔记

    前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦!       CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...

  9. [摸鱼]cdq分治 学习笔记

    待我玩会游戏整理下思绪(分明是想摸鱼 cdq分治是一种用于降维和处理对不同子区间有贡献的离线分治算法 对于常见的操作查询题目而言,时间总是有序的,而cdq分治则是耗费\(O(logq)\)的代价使动态 ...

最新文章

  1. 委员建议开辟多种科研资助模式,呼唤“科研悬赏制”
  2. oracler日期函数相差六个月_Oracle数据库之SQL单行函数---日期函数集锦
  3. go语言中的引用类型
  4. ubuntu怎么清空回收站?(权限不够)
  5. wordpress 新建php文件大小,WordPress最大上传文件大小限制修改
  6. dg oracle 切换模式_谈谈dg切换涉及的概念:switchover和failover区别
  7. ehcache 一二事 - ssm 中ehcashe的简单配置应用
  8. VMware虚拟机Centos7配置双网卡双IP踩坑
  9. 均匀带电直线外一点的场强
  10. 数字电子技术基础笔记(精简)
  11. Python3.6 word批量转换为txt提取
  12. 2014传智播客ios第4期基础班+就业班
  13. 定义一个函数,返回整形数组中最大值
  14. 后门攻击阅读笔记,Input-aware dynamic backdoor attack
  15. 台式计算机不同处理器型号,买电脑不要再被坑了,CPU型号解读
  16. Postman请求报405错误
  17. Scratch节假日主题课:植树节种五棵树
  18. 美国国土安全部仍然使用 COBOL 语言
  19. 华三,思科ACL命令解析
  20. 使用 Webmin+bind9快速搭建私有DNS服务器

热门文章

  1. modernizr 支持html5,使用modernizr.js检测浏览器对html5以及css3的支持情况
  2. python opencv imread()函数,关于:灰度图(二维数组图),彩色图(三维数组图)
  3. 【MySQL】(图解)快速理解内连接、外连接、左连接、右连接
  4. 【建站系列教程】2.2、fiddler手机抓包教程
  5. numpy中的cov(方差计算)简单介绍
  6. LetCode 70. Climbing Stairs--动态规划-爬梯子--递归等解法
  7. 联想输入快捷键_UG软件F8快捷键和笔记本电脑F8快捷键冲突的解决方法
  8. 鸿蒙电视哔哩哔哩,[4K视频] 65寸智能电视只要3299元?荣耀智慧屏X1开箱
  9. c语言const与*位置关系,C语言程序的存储区域与const关键字的使用方法
  10. Swift如何使用Masonry和SnapKit