分治算法,逆序对,三维偏序与CDQ分治

本文为博客 VIP 文章,开通 VIP 后可阅读全文

开通 VIP

分治算法基本思想

当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出。

对于这类问题,我们往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法。

如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。这就是分治策略的基本思想。

归并排序


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5,oo=2*1e9;
int n,L[maxn],R[maxn],a[maxn];
void merge(int l,int mid,int r){
	int n1=mid-l+1;
	int n2=r-mid;//r-(mid+1)+1
	for(int i=1;i<=n1;i++)L[i]=a[i+l-1];
	for(int i=1;i<=n2;i++)R[i]=a[i+mid];//i+(mid+1)-1
	L[n1+1]=oo;
	R[n2+1]=oo;//哨兵 
	int x=1,y=1;
	for(int i=l;i<=r;i++){
		if(L[x]<R[y])a[i]=L[x++];
		else a[i]=R[y++];
	}
	return ;
}
void solve(int l,int r){
	if(l>=r)return ;
	int mid=(l+r)/2;
	solve(l,mid);
	solve(mid+1,r);//分治 
	merge(l,mid,r);//合并子问题 
	return ;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	solve(1,n);
	for(int i=1;i<=n;i++)cout<<a[i]<<" ";
	return 0;
}

用分治算法实现逆序对

P1908 逆序对

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+5,oo=2*1e9;
int n,L[maxn],R[maxn],a[maxn];
long long ans=0;
void merge(int l,int mid,int r){
	int n1=mid-l+1;
	int n2=r-mid;//r-(mid+1)+1
	for(int i=1;i<=n1;i++)L[i]=a[i+l-1];
	for(int i=1;i<=n2;i++)R[i]=a[i+mid];//i+(mid+1)-1
	L[n1+1]=oo;
	R[n2+1]=oo;//哨兵 
	int x=1,y=1;
	for(int i=l;i<=r;i++){
		if(L[x]<R[y])a[i]=L[x++];
		else a[i]=R[y++];
	}
	x=y=1;
	while(y<=n2){
		if(L[x]>R[y])ans+=n1-x+1,y++;//计算逆序对的数量 
		else x++; 
	}
	return ;
}
void solve(int l,int r){
	if(l>=r)return ;
	int mid=(l+r)/2;
	solve(l,mid);
	solve(mid+1,r);//分治 
	merge(l,mid,r);//合并子问题 
	return ;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	solve(1,n);
	cout<<ans;
	return 0;
}

二维偏序

定义:

形如 xi<xjx_i<x_jxi​<xj​ 且 yi<yjy_i<y_jyi​<yj​ 之类的约束条件,我们可以称为二维偏序。

逆序对就是一个非常经典的二位偏序。

解决:

如果按照暴力想法,我们 O(n2)O(n^2)O(n2)的时间枚举 i,ji,ji,j,这样太慢了。

处理第 iii 位时,我们已经处理过 [1,i−1]\left[ 1,i-1 \right][1,i−1] 的数量,那么我们可不可以用一个数据结构记录一下之前的情况呢?

这就引出了二维偏序。

我们把第一维从小到大排序,然后遍历,将第二位插入树状数组中,每次查询,即可解决问题。

例题:

有n个学生,第i个学生有两个技巧:x[i]x\left[ i \right]x[i] 和 y[i]y\left[ i \right ] y[i] ,不存在两个学生的技巧完全相同。

如果 x[j]≤x[i]x[j]\leq x[i]x[j]≤x[i] 且 y[j]≤[i]y[j]\leq [i]y[j]≤[i] ,那么学生 iii 就是比学生 jjj 强,学生 jjj 比学生 iii 弱。

假设总共有 aaa 个学生比第 iii 个学生弱,那么第 iii 个学生的等级就是 aaa 。

现在的问题是,依次输出:

有多少个学生的等级是 000 ?

有多少个学生的等级是 111 ?

有多少个学生的等级是 222 ?

......

有多少个学生的等级是 n−1n-1n−1 ?

输入格式

第一行,一个整数nnn。1≤n≤1000001\leq n\leq 1000001≤n≤100000。

接下来n行,第i行有两个整数x[i]x[ i ]x[i]和y[i]y[ i ]y[i]。 1≤x[i],y[i]≤10000001\leq x[i],y[i]\leq 10000001≤x[i],y[i]≤1000000

输出格式

共nnn行,每行一个整数。

输入:

5

1 1

5 1

7 1

3 3

5 5

输出:

1 2 1 1 0

代码:

#include<bits/
在ubuntu20.04上配置VINS_Fusion(亲测有效,一应俱全) 最近在做科研训练的时候配置了HKUST-Aerial-Robotics实验室的VINS_Fusion代码项目,经历了一些编译报错的问题,在网上查找的时候博客内容良莠不齐,且实质针对性意见不多,于是在此记录下自己配置期间遇到的一些共性问题,留作自己日后参考和大家的交流学习。 阅读详情

相关推荐

多测师肖sir_高级金牌讲师_数据库之存储练习题(8.13.1)

实验 一、 实验要求: 理解存储过程的概念 掌握存储过程的语法格式、使用方法 掌握存 储过程的创建、执行 二、实验前提: – drop table if exists student; – Create table student – (Id varchar(255), #学号 – Name varchar(255), #姓名 – Roomid varchar(255), #班级 – Sex char(1), #性别 – Degree varchar(3) );#成绩; Insert into stud

多测师肖sir的博客 653

算法竞赛学习笔记】CDQ分治以及例题

title : CDQ分治 date : 2021-9-12 tags : ACM,分治 简介 CDQ分治普通分治的不同,在于需要同时考虑[L,M]内的修改对[M+1,R]内的查询产生的影响。 CDQ分治解决什么问题 (1)和点对相关的问题 (2)优化DP的转移 (3)将一些动态的问题转化为静态问题 (4)三维偏序问题 一般步骤 (1)将整个操作序列分为两个长度相等的部分 (2)递归处理前一部分的子问题 (3)计算前一部分的子问题中的修改操作对后一部分子问题的影响 (4)递归处理后一部分的子问题 三.

SC_Linno的博客 995

武汉理工大学《机械设计基础》历年期末考研试卷(整合版,部分含答案).pdf

武汉理工大学《机械设计基础》历年期末考研试卷(整合版,部分含答案

偏序:正逆序比

同一个集合( query相同 ) 的两个样本,在特征(模型计算所得)上的大小关系在 label 上的大小关系相反,称为逆序,那么,同一个集合内的逆序对数目为逆序对数。同一个集合( query相同 ) 的两个样本,在特征(模型计算所得)上的大小关系在 label 上的大小关系相同,称为正序,那么,同一个集合内的正序对数目为正序对数。正序对数 / 逆序对数,在排序问题中,正逆序比是衡量一个特征区分度的重要指标,一个特征的正逆序值越大,它的效果越理想。第四行向上数,1个正序对,2个逆序对

雄关漫道真如铁 而今迈步从头越 2363

三维偏序/cdq分治/

三维偏序---cdq分治cdq分治概述三维偏序概述例题分析代码模板 cdq分治概述 cdq 分治和dp一样,是一种思想而不是具体的算法,因此 cdq 分治涵盖的范围相当的广泛,由于这样的思路最早是被陈丹琦引入国内的,所以就叫 cdq 分治了。 cdq分治可解决的问题大致可分为三类: 点对有关的问题(三维偏序cdq 分治优化 1D/1D 动态规划的转移(还不懂 ) 通过 cdq 分治,将一些动态问题转化为静态问题 本篇博客主要介绍和总结用cqd分治解决的三维偏序问题 三维偏序概述 三维偏序,听起来似

lijing_er的博客 3237

CDQ分治详解,一维、二维、三维偏序

如何利用CDQ分治解决偏序问题

EQUINOX1的博客 5524

[BZOJ3295]动态逆序对CDQ分治

这,其实如果真的想清楚了,大概···其实就一个CDQ模板题 只是这道题在每个CDQ执行的时候,影响需要分两部分计算题解题目我就不写了······直接写方法 我们可以把删除操作倒着看成插入,这样对于每一个数字就多了一个时间维,在时间约束下的逆序对,就是三位偏序。 第一维是插入时间,第二维是位置,第三维是值。判断依据:1.插入时间早的对插入时间晚的可能产生贡献 2.位置靠前并且值比较大的,对位置

泉華子的OI足迹 427

CDQ分治分治(真得头疼)

前言: 说实话我对于这种没有固定板子,变化多端的算法实在是非常头疼的 但是不学不行,这也是一种很重要的思伟方式 所以趁着这几天的心情比较好(快要放大周),赶紧学一波~鸣谢:tham,stdcallCDQ分治,传说中是一个♀神犇创造的算法 在了解这种算法之前,我们有必要了解一下一种基本的思想:分治知识储备:分治 分治介绍 分而治之,将原问题不断划分成若干个子问题,直到子问题规模小到足以直接解

Coco_T的博客 2万+

算法CDQ分治 -- 三维偏序 & 动态逆序对

初次接触CDQ分治,感觉真的挺厉害的。整体思路即分而治之,再用之前处理出来的答案统计之后的答案。 大概流程是(对于区间 l ~ r): 1.处理 l ~mid, mid + 1 ~ r 的答案; 2.分别排序规整; 3.计算 l ~ mid 中每一个数对 mid + 1 ~ r 中的答案的贡献, 累加; 4.得到区间l ~ r的答案。 CDQ分治我一共也才做了两道题目, 就一起整理在这...

weixin_30345577的博客 193

cdq分治和多维偏序问题』

更新了三维偏序问题的拓展 cdq分治 \(cdq\)分治是一种由\(IOI\ Au\)选手\(cdq\)提出的离线分治算法,又称基于时间的分治算法。 二维偏序问题 这是\(cdq\)分治最早提出的时候解决的问题,大意为:给定\(n\)对二元组\((a_{i},b_{i})\),求\(cnt_i=\sum_{j=i+1}^n[a_j>a_i\ and \ b_j>b_i]\...

weixin_34248705的博客 125

[Cqoi2011]动态逆序对CDQ分治三维偏序

题目链接 还是不会CDQ分治啊,还是看着博客思索着思路的,虽然知道该走哪个方向,但是代码仍然还是写不出来啊呜呜呜! 首先,就是把删除当作反向插入的这样一个过程倒是比较好想到,但是后面呢,我们得到了它们各自的时间戳,相当于把原来的每个数变成了(t, x, y)这样的形式了,那么我们就是需要去求的是合法的时间戳内,逆序对的个数了,不妨可以看成对应的时间戳上,产生的贡献是多少。 CDQ...

既然弱小,就只顾变强就是了 294

归并排序和cdq分治

先上一个归并排序的代码: #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=5e5+9; int a[N],temp[N],n; ll ans=0; void merge_sort(int l,int r){ if(l==r)return; int mid=(...

IQ^QI的博客 280

CDQ分治

CDQ分治是种离线的分治算法 通常解决带有修改和问询且不强制在线的一类问题 本人菜鸡,就只能推推文章这样子 ==> CDQ分治 说一些点 ① CDQ的优点就是能起到降维的作用,从而顶替了本应多套一层数据结构才能维护的信息 具体点来说就是“消除了某一维”的影响、例如在解决三维偏序的过程中,先根据a、b、c排序 分治时根据 b 排序,这时各个区间的 a 元素可能...

183

简单入门CDQ分治(很有意思的算法

最近因为牛客暑期多校的一道题涉及到了CDQ分治,于是便去学习了一下CDQ分治CDQ分治是以曾经的IOI选手陈丹琦命名的一种强大的算法,主要用于解决偏序问题,通过对一维进行排序(在这里说的总维度为二维),再对其它维度进行分治。 再来讲讲CDQ分治的特点,普通分治是将原问题划分为若干个子问题,每个子问题相互独立且原问题形式相同,递归求解子问题,最后...

asdfghjkl999999999的博客 393

CDQ分治:让偏序问题“降维打击”

CDQ分治:让偏序问题“降维打击”

船漏了就会沉的博客 423

CDQ分治学习笔记

数据结构中的一块内容:$CDQ$分治算法。 $CDQ$显然是一个人的名字,陈丹琪(NOI2008金牌女选手) 这种离线分治算法算法界称为"cdq分治" 我们知道,一个动态的问题一定是由"更改""查询"操作构成的,显然,有些“更改”会改变"查询的结果",而有些不能 如果我们合理安排一个次序,把每一个查询分成几个部分,分别计算值,最后合起来就是原来询问的值。 离线算法和在线算法的...

weixin_30690833的博客 167

CDQ分治,二维数点三维数点,p1357p2026p2027p2028p2029

  多方查找找到了2008年陈丹琪引入CDQ分治的 从《Cash》谈一类分治算法的应用.doc ,CDQ分治的名字由来也是她.   什么叫CDQ分治呢?来看一道二维数点题p1357.      看了一眼题,我会树状数组!   现在拿它来引入CDQ分治.先全部按照x排序,由于区间[mid+1,r]不会再对区间[l,mid]有贡献,对于区间[l,r]内的贡献都可以分三步进行.   ...

weixin_30826761的博客 297
上一篇: 树状数组的基本操作
下一篇: 容斥原理的妙用
tanjianlang
博客等级 码龄6年 0粉丝 9原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值