cdq 系列 题解

从二维数点(二维偏序)到三维偏序。

用 cdq 分治可以解决二维数点问题。

1.洛谷 P1908 逆序对

题意

求所有数对 ( i , j ) (i,j) (i,j) 的个数,满足 i < j i<j i<j a i > a j a_i>a_j ai>aj

1 ≤ n ≤ 5 × 1 0 5 1\le n \le 5\times10^5 1n5×105

思路

欲学习树状数组解法的,请移步这里。这里用 cdq 分治的作为复习。

在很久很久以前,我们介绍过归并排序,说到可以使用归并排序的思想来解决这样的逆序对(二维偏序、二维数点)问题,也可以用于找一些特定的数对。

cdq 分治是一种思想,体现的当然是“分而治之”。处理区间 ( l , r ) (l,r) (l,r),其流程大概为:

  • 找到中点 m i d mid mid
  • 将所有可能存在的点对分为三类:
    1 . i ∈ [ l , m i d ] , j ∈ [ l , m i d ] i\in[l,mid],j\in[l,mid] i[l,mid],j[l,mid]
    2 . i ∈ [ l , m i d ] , j ∈ [ m i d + 1 , r ] i\in[l,mid],j\in[mid+1,r] i[l,mid],j[mid+1,r];
    3 . i ∈ [ m i d + 1 , r ] , j ∈ [ m i d + 1 , r ] i\in[mid+1,r],j\in[mid+1,r] i[mid+1,r],j[mid+1,r]
  • 递归处理第 1 , 3 1,3 1,3 类;
  • 设法处理第 2 2 2 类。

(以上参考自OI - WIKI)

严格来说,这种二维偏序题并不能算作 cdq 分治,其实只是分治思想和双指针的应用。我们考虑双指针 p ∈ [ l , m i d ] p\in[l,mid] p[l,mid] q ∈ [ m i d + 1 , r ] q\in[mid+1,r] q[mid+1,r]

  • 如果 a p ≤ a q a_p\le a_q apaq,那么当前 p p p 并不能对 q q q 产生贡献,我们考虑将 p p p 合并到新数组 b b b 去;
  • 否则即 a p > a q a_p>a_q ap>aq,因为 p < q p<q p<q 所以此时产生了逆序对,可以产生贡献;
  • 因为我们已经分治处理了 l ∼ m i d l\sim mid lmid m i d + 1 ∼ r mid+1\sim r mid+1r,所以以 m i d mid mid 分开的左右两段区间都已经是有序的了(上一步的合并操作),所以 a q a_q aq l ∼ p − 1 l\sim p-1 lp1 的都要大,比 p ∼ m i d p\sim mid pmid 的都要小,所以逆序对个数增加 m i d − p + 1 mid-p+1 midp+1 个;
  • 那么 a q a_q aq 已经不能产生接下来的逆序对,扔进 b b b

记得把已经排序好了的 b b b 数组复制到 a l ∼ r a_{l\sim r} alr 去:

void cdq(ll l,ll r)
{if(l>=r)return;ll mid=(l+r)>>1;cdq(l,mid);cdq(mid+1,r);ll i=l,p=l,q=mid+1;while(p<=mid&&q<=r){if(q>r||p<=mid&&a[p]<=a[q])b[i++]=a[p++];//并入没法贡献的p else {b[i++]=a[q++];cnt+=mid-p+1;//a(i)>a(j)的数量,取右边大的 }}while(p<=mid)b[i++]=a[p++];while(q<=r)cnt+=mid-p+1,b[i++]=a[q++];for(int o=l;o<=r;o++)a[o]=b[o];
}

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=5e5+9;
ll n,a[N];
ll b[N],cnt;
void cdq(ll l,ll r)
{if(l>=r)return;ll mid=(l+r)>>1;cdq(l,mid);cdq(mid+1,r);ll i=l,p=l,q=mid+1;while(p<=mid&&q<=r){if(q>r||p<=mid&&a[p]<=a[q])b[i++]=a[p++];//并入没法贡献的p else {b[i++]=a[q++];cnt+=mid-p+1;//a(i)>a(j)的数量,取右边大的 }}while(p<=mid)b[i++]=a[p++];while(q<=r)cnt+=mid-p+1,b[i++]=a[q++];for(int o=l;o<=r;o++)a[o]=b[o];
}
int main()
{scanf("%lld",&n);for(int i=1;i<=n;i++)scanf("%lld",&a[i]);cdq(1,n);printf("%lld",cnt);return 0;
}

2.洛谷 P2717 寒假作业/P2804 神秘数字

题意

给定一个长度为 n n n 的正整数序列 a i a_i ai,求出有多少个连续子序列的平均值不小于 k k k

1 ≤ n ≤ 1 0 5 1\le n\le 10^5 1n105 1 ≤ ∀ a i , k ≤ 1 0 4 1\le \forall a_i,k\le 10^4 1ai,k104

洛谷 P2804:要求平均值严格大于 k k k

这里按照洛谷 P2717 的题面进行讲解。

思路

在这里我们讲到,这是一个“顺序对”:求所有 l < r , s l ≤ s r l<r,s_l\le s_r l<r,slsr 的个数,我们只要取比 a q a_q aq 小的左边: l ∼ p − 1 l\sim p-1 lp1即可,每次贡献加 p − l p-l pl

因为是前缀和数组,所以 l = 0 l=0 l=0 是合法的,记得从 0 0 0 开始。

代码 1 - 寒假作业

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=1e5+9;
ll n,k,a[N];
ll s[N],cnt,b[N];
void cdq(ll l,ll r) 
{if(l>=r)return;ll mid=(l+r)>>1;cdq(l,mid);cdq(mid+1,r);ll i=l,p=l,q=mid+1;while(p<=mid&&q<=r){if(s[p]<=s[q])b[i++]=s[p++];else {cnt+=p-l;//s(i)<s(j),取左边小的 b[i++]=s[q++];}}while(p<=mid)b[i++]=s[p++];while(q<=r)cnt+=p-l,b[i++]=s[q++];for(ll o=l;o<=r;o++)s[o]=b[o];
}
int main()
{scanf("%lld%lld",&n,&k);for(ll i=1;i<=n;i++){scanf("%lld",&a[i]);a[i]-=k;s[i]=s[i-1]+a[i];}cdq(0,n);printf("%lld",cnt);return 0;
}

2 2 2 题,要求严格大于,所以只需要改成:

if(s[p]<s[q])b[i++]=s[p++];

即可。记得取题目规定的模。

3.洛谷 P2163 SHOI2007 园丁的烦恼

4.洛谷 P3157 CQOI2011 动态逆序对/UVA11990 "Dynamic’’ Inversion

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/77603.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机组成与体系结构:内存接口(Memory Interface)

目录 什么是内存接口 &#xff1f; 为什么需要特别设计“接口”&#xff1f; 什么是 MIPS&#xff1f;为什么它和内存接口有关&#xff1f; 内存接口的两种访问方式 串行访问&#xff08;Serial Access Model&#xff09; 并行访问&#xff08;Parallel Access Model&…

Java面试(2025)—— Spring MVC

什么是Spring MVC Spring MVC 是 Spring 框架的一个 基于 Java 的 Web 开发模块&#xff0c;它实现了 MVC&#xff08;Model-View-Controller&#xff09;架构模式&#xff0c;用于构建灵活、松耦合的 Web 应用程序。 它是 Spring 生态的核心组件之一&#xff0c;通过简化 HTT…

天翼云手机断开连接2小时关机

2025-04-21 天翼云手机断开连接2小时自动 天翼云手机 4元1个月 天翼云手机永不关机 天翼云手机不休眠 天翼云手机断开连接时&#xff0c;界面显示&#xff1a;离线运行&#xff0c;2小时后自动关机 电脑每小时自动连接一次 手机每小时自动连接一次

Redis——数据结构

目录 1.动态字符串SDS 1.1SDS底层源码 1.2 SDS动态扩容 1.3动态字符串SDS优点 2.IntSet 2.1底层结构 2.2有序性 2.3.IntSet结构扩容 2.4总结 3.Dict 3.1底层结构 3.2.Dict扩容 3.3Dict收缩 3.4.Dict的rehash 1.分配空间 2. 设置 rehashidx 3. 渐进式 rehash…

C++ GPU并行计算开发实战:利用CUDA/OpenCL加速粒子系统与流体模拟

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…

LeetCode算法题(Go语言实现)_54

题目 给你两个正整数数组 spells 和 potions &#xff0c;长度分别为 n 和 m &#xff0c;其中 spells[i] 表示第 i 个咒语的能量强度&#xff0c;potions[j] 表示第 j 瓶药水的能量强度。 同时给你一个整数 success 。一个咒语和药水的能量强度 相乘 如果 大于等于 success &a…

内网穿透快解析免费开放硬件集成SDK

一、行业问题 随着物联网技术的发展&#xff0c;符合用户需求的智能硬件设备被广泛的应用到各个领域&#xff0c;而智能设备的远程运维管理也是企业用户遇到的问题 二、快解析内网穿透解决方案 快解析是一款内网穿透产品&#xff0c;可以实现内网资源在外网访问&#xff0c;…

Python+Word实现周报自动化的完整流程

一、技术方案概述 自动化报表解决方案基于以下技术组件&#xff1a; Python 作为核心编程语言python-docx 库用于处理 Word 文档pandas 库用于数据处理和分析matplotlib 或 plotly 库用于数据可视化Word 模版作为报表的基础格式 这种方案的优势在于&#xff1a;保留了 Word 文…

elastic/go-elasticsearch与olivere/elastic

在 Go 语言中&#xff0c;与 Elasticsearch 交互的客户端库有多种选择&#xff0c;其中 github.com/elastic/go-elasticsearch/v8 和 github.com/olivere/elastic/v7 是两个常用的库。这两个库的功能和用途有一些差异&#xff0c;以下是它们的详细对比&#xff1a; 1. github.c…

deepseek + kimi制作PPT

目录 一、kimi简介二、deepseek生成内容三、生成PPT四、编辑PPT 一、kimi简介 kimi是一款只能ppt生成器&#xff0c;擅长将文本内容生成PPT。 在这里&#xff0c;​​DeepSeek 负责内容生成与逻辑梳理​​&#xff0c;​​Kimi 优化表达与提供设计建议​​。 二、deepseek生…

【八大排序】冒泡、直接选择、直接插入、希尔、堆、归并、快速、计数排序

目录 一、排序的介绍二、排序算法的实现2.1 直接插入排序2.2 希尔排序2.3 直接选择排序2.4 堆排序2.5 冒泡排序2.6 快速排序2.7 归并排序2.8 比较排序算法的性能展示2.9 计数排序 个人主页<— 数据结构专栏<— 一、排序的介绍 我们的生活中有很多排序&#xff0c;比如像…

linux 查询目录文件大小

​ 在 Linux 系统中&#xff0c;准确地掌握目录和文件的大小对于磁盘空间管理至关重要。​本文将详细介绍如何使用 du&#xff08;disk usage&#xff09;命令逐层查看目录和文件的大小&#xff0c;并结合 sort 命令对结果进行排序&#xff0c;以便有效地识别和管理占用…

如何简单几步使用 FFmpeg 将任何音频转为 MP3?

在多媒体处理领域&#xff0c;FFmpeg 以其强大的功能和灵活性而闻名。无论是视频编辑、音频转换还是流媒体处理&#xff0c;它都是专业人士和技术爱好者的首选工具之一。在这篇文章中简鹿办公将重点介绍如何使用 FFmpeg 进行音频格式转换&#xff0c;提供一些常用的转换方式&am…

通信信号分类识别

通信信号分类识别 AlexNet网络识别InceptionV3、ResNet-18、ResNet-50网络识别 采用短时傅里叶变换将一维信号转换为二维信号&#xff0c;然后采用经典神经网络进行识别 支持识别BASK,BFSK,BPSK,QPSK,8PSK,QAM和MSK。 AlexNet网络识别 在这里插入图片描述 InceptionV3、Re…

TPshop项目-服务器环境部署(部署环境/服务,检查部署环境/服务,上传TPshop项目到服务器,配置文件的更改,安装TPshop)

目录 部署环境/服务&#xff0c;检查部署环境/服务 检查部署环境/服务 上传TPshop项目到服务器&#xff0c;配置文件的更改&#xff0c;安装TPshop 部署环境/服务&#xff0c;检查部署环境/服务 一般部署环境&#xff0c;会根据开发写的部署文档来一步一步的部署环境。 部署…

C++入门基础:命名空间,缺省参数,函数重载,输入输出

命名空间&#xff1a; C语言是基于C语言的&#xff0c;融入了面向对象编程思想&#xff0c;有了很多有用的库&#xff0c;所以接下来我们将学习C如何优化C语言的不足的。 在C/C语言实践中&#xff0c;在全局作用域中变量&#xff0c;函数&#xff0c;类会有很多&#xff0c;这…

缓存 --- Redis基本数据类型

缓存 --- Redis基本数据类型 Redis Intro5种基础数据类型 Redis Intro Redis&#xff08;Remote Dictionary Server&#xff09;是一款开源的高性能键值存储系统&#xff0c;常用于缓存、消息中间件和实时数据处理场景。以下是其核心特点、数据类型及典型使用场景&#xff1a; …

Redis命令——list

列表类型是用来存储多个有序的字符串&#xff0c;列表中的每个字符串称为元素&#xff08;element&#xff09;&#xff0c;⼀个列表最多可以存储个元素 在 Redis 中&#xff0c;可以对列表两端插入&#xff08;push&#xff09;和弹出&#xff08;pop&#xff09;&#xff0c;…

Android Jetpack Compose 状态管理解析:remember vs mutableStateOf,有啥不一样?为啥要一起用?

&#x1f331;《Jetpack Compose 状态管理解析&#xff1a;remember vs mutableStateOf&#xff0c;有啥不一样&#xff1f;为啥要一起用&#xff1f;》 在 Jetpack Compose 的世界里&#xff0c;UI 是响应式的。这意味着当状态发生变化时&#xff0c;UI 会自动重组&#xff0…

使用 PCL 和 Qt 实现点云可视化与交互

下面我将介绍如何结合点云库(PCL)和Qt框架(特别是QML)来实现点云的可视化与交互功能&#xff0c;包括高亮选择等效果。 1. 基本架构设计 首先需要建立一个结合PCL和Qt的基本架构&#xff1a; // PCLQtViewer.h #pragma once#include <QObject> #include <pcl/point…