当前位置: 首页 > news >正文

Codeforces Round 240 (Div. 1) C. Mashmokh and Reverse Operation(分治+逆序对)

原题链接:C. Mashmokh and Reverse Operation


题目大意:


给出一个长度为 2 n 2^{n} 2n 的正整数数组 a a a ,再给出 m m m 次操作。

每次操作给出一个数字 q q q ,把数组分为 2 n − q 2^{n-q} 2nq 个长度为 2 q 2^{q} 2q 的段,然后每段执行一次翻转操作,操作完后输出当前数组的逆序对数量。

分段操作: [ a 1 , a 2 , . . . , a 2 q ] , [ a 2 q + 1 , a 2 q + 2 , . . . , a 2 q + 1 ] , . . . , [ a 2 n − 1 + 1 , a 2 n − 1 + 2 , . . . , a 2 n ] [a_{1},a_{2},...,a_{2^q}],[a_{2^{q}+1},a_{2^{q}+2},...,a_{2^{q+1}}],...,[a_{2^{n-1}+1},a_{2^{n-1}+2},...,a_{2^{n}}] [a1,a2,...,a2q],[a2q+1,a2q+2,...,a2q+1],...,[a2n1+1,a2n1+2,...,a2n]

翻转操作: [ a 2 q , a 2 q − 1 , . . . , a 1 ] , [ a 2 q + 1 , a 2 q − 1 , . . . , a 2 q + 1 ] , . . . , [ a 2 n , a 2 n − 1 , . . . , a 2 n − 1 + 1 ] [a_{2^{q}},a_{2^{q}-1},...,a_{1}],[a_{2^{q+1}},a_{2^{q}-1},...,a_{2^{q}+1}],...,[a_{2^{n}},a_{2^{n}-1},...,a_{2^{n-1}+1}] [a2q,a2q1,...,a1],[a2q+1,a2q1,...,a2q+1],...,[a2n,a2n1,...,a2n1+1]

每次操作会改变原数组,并且都要输出操作完后逆序对的数量。

解题思路:


很有意思的分治归并排序题。

首先发现我们数组长度是 2 2 2 的次幂,且每次分段长度也都是 2 2 2 的次幂,暗示我们可以向着分治的方向去思考。

我们知道:逆序对 + + + 顺序对 = n ⋅ ( n − 1 ) 2 =\frac{n \cdot(n-1)}{2} =2n(n1) 其中 n n n 为区间长度。

我们将一个区间翻转时,本质上就是将逆序对的值和顺序对的值交换了一下,因为本来逆序的翻转之后就变成顺序的了。

这样类似将数组分成一段段的 2 2 2 次幂长度,我们考虑可以考虑类似归并排序的分治方法。

归并排序是在排序的过程中同时算出每一层的逆序对,然后相加每层得到的逆序对,从而得到整个原数组的逆序对的。

假设原数组 a a a [ 4 , 5 , 7 , 1 , 3 , 6 , 8 , 2 ] [4,5,7,1,3,6,8,2] [4,5,7,1,3,6,8,2] ,我们画出归并排序树看看:

3 : [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] 7 3:[1,2,3,4,5,6,7,8]^{7} 3:[1,2,3,4,5,6,7,8]7
2 : [ 1 , 4 , 5 , 7 ] 2 , [ 2 , 3 , 6 , 8 ] 2 2:[1,4,5,7]^{2},[2,3,6,8]^{2} 2:[1,4,5,7]2,[2,3,6,8]2
1 : [ 4 , 5 ] 0 , [ 1 , 7 ] 1 , [ 3 , 6 ] 0 , [ 2 , 8 ] 1 1:[4,5]^{0},[1,7]^{1},[3,6]^{0},[2,8]^{1} 1:[4,5]0,[1,7]1,[3,6]0,[2,8]1
0 : [ 4 ] , [ 5 ] , [ 7 ] , [ 1 ] , [ 3 ] , [ 6 ] , [ 8 ] , [ 2 ] 0:[4],[5],[7],[1],[3],[6],[8],[2] 0:[4],[5],[7],[1],[3],[6],[8],[2]

(右上角角标为将该层排好序时得到的逆序对数量,叶子层(第 0 0 0 层)均为 0 0 0 就不做标记了)

那么总的逆序对数就是所有层角标相加之和: 7 + 2 + 2 + 0 + 1 + 0 + 1 = 13 7+2+2+0+1+0+1=13 7+2+2+0+1+0+1=13 对。

我们考虑将区间长度为 2 1 2^{1} 21 的段全翻转,看看会造成什么影响。

3 : [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] 7 3:[1,2,3,4,5,6,7,8]^{7} 3:[1,2,3,4,5,6,7,8]7
2 : [ 1 , 4 , 5 , 7 ] 2 , [ 2 , 3 , 6 , 8 ] 2 2:[1,4,5,7]^{2},[2,3,6,8]^{2} 2:[1,4,5,7]2,[2,3,6,8]2

1 ′ : [ 4 , 5 ] 1 , [ 1 , 7 ] 0 , [ 3 , 6 ] 1 , [ 2 , 8 ] 0 1':[4,5]^{1},[1,7]^{0},[3,6]^{1},[2,8]^{0} 1:[4,5]1,[1,7]0,[3,6]1,[2,8]0
0 ′ : [ 5 ] , [ 4 ] , [ 1 ] , [ 7 ] , [ 6 ] , [ 3 ] , [ 2 ] , [ 8 ] 0':[5],[4],[1],[7],[6],[3],[2],[8] 0:[5],[4],[1],[7],[6],[3],[2],[8]

那么总的逆序对数就是 7 + 2 + 2 + 1 + 0 + 1 + 0 = 13 7+2+2+1+0+1+0=13 7+2+2+1+0+1+0=13 对。

可以发现,我们只有在第 1 → 0 1 \rightarrow 0 10 层往下的所有层逆序对被改变了,即顺序对和逆序对交换了,而其他层 n → 2 n \rightarrow 2 n2 层则无变化。

因为归并到第 0 → i 0 \rightarrow i 0i 层前,其下的所有层是在做 边排序边计算 的过程,因此无论其下层的顺序是怎么样的,最终数组 排序 到到第 i i i 层时的状态都是唯一确定的,不会影响到上一层。

比如我们修改前的第 1 1 1 层,和我们原数组的第 1 1 1 层状态是相同的,只有逆序对和顺序对的角标被改变了。

同理,无论按何种顺序如何翻转第 2 q 2^{q} 2q 层,其只会影响第 0 → q 0 \rightarrow q 0q 的逆序对状态,而不会影响第 q + 1 → n q+1 \rightarrow n q+1n 层逆序对的状态。

因此,我们先对原数组做一次归并排序,同时记录每一层的逆序对状态,和顺序对状态。

对每次的修改,对 1 → q 1 \rightarrow q 1q 层直接交换顺序对和逆序对的值(第 0 0 0 层全是 0 0 0 ,可以不管),其余不变(或者用 2 n − q ⋅ 2 q ⋅ ( 2 q − 1 ) 2 − 2^{n-q} \cdot \frac{2^{q} \cdot (2^{q}-1)}{2}- 2nq22q(2q1)当前层逆序对之和,不过有个 2 2 2 的次幂,比较麻烦)。

交换完后,统计所有层的逆序对之和就是我们的答案了。

时间复杂度: O ( n log ⁡ n + q log ⁡ n ) O(n \log n+q \log n) O(nlogn+qlogn)

AC代码:

#include <bits/stdc++.h>
using namespace std;using PII = pair<int, int>;
using i64 = long long;void solve() {int n;cin >> n;vector<int> a((1 << n) + 1);for (int i = 1; i <= (1 << n); ++i) {cin >> a[i];}vector cnt(n + 1, vector<i64>(2));vector<int> b(1 << n);auto Msort = [&](auto self, int l, int r, int dep) -> void {if (l >= r) return;int mid = l + r >> 1, i = l, j = mid + 1, k = 0;self(self, l, mid, dep - 1), self(self, mid + 1, r, dep - 1);//求顺序对while (i <= mid && j <= r) {if (a[i] < a[j]) {cnt[dep][1] += r - j + 1;++i;} else {++j;}}//求逆序对并同时将数组排序i = l, j = mid + 1;while (i <= mid && j <= r) {if (a[i] > a[j]) {cnt[dep][0] += mid - i + 1;b[k++] = a[j++];} else {b[k++] = a[i++];}}while (i <= mid) {b[k++] = a[i++];}while (j <= r) {b[k++] = a[j++];}for (i = l, j = 0; i <= r; ++i, ++j) {a[i] = b[j];}};Msort(Msort, 1, 1 << n, n);int q;cin >> q;for (int i = 1; i <= q; ++i) {int d;cin >> d;i64 ans = 0;//修改d层 则将 [1, d] 层的值全部交换一下for (int j = 1; j <= n; ++j) {if (j <= d) {swap(cnt[j][0], cnt[j][1]);}ans += cnt[j][0];}cout << ans << '\n';}
}signed main() {ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);int t = 1; //cin >> t;while (t--) solve();return 0;
}

相关文章:

Codeforces Round 240 (Div. 1) C. Mashmokh and Reverse Operation(分治+逆序对)

原题链接&#xff1a;C. Mashmokh and Reverse Operation 题目大意&#xff1a; 给出一个长度为 2 n 2^{n} 2n 的正整数数组 a a a &#xff0c;再给出 m m m 次操作。 每次操作给出一个数字 q q q &#xff0c;把数组分为 2 n − q 2^{n-q} 2n−q 个长度为 2 q 2^{q} 2…...

SpringBoot源码解读与原理分析(三十二)SpringBoot整合JDBC(一)JDBC组件的自动装配

文章目录 前言第10章 SpringBoot整合JDBC10.1 SpringBoot整合JDBC的项目搭建10.1.1 初始化数据库10.1.2 整合项目10.1.2.1 导入JDBC和MySQL驱动依赖10.1.2.2 配置数据源 10.1.3 编写业务代码10.1.3.1 编写与t_user表对应的实体类User10.1.3.2 编写Dao层代码10.1.3.3 编写Servic…...

petalinux_zynq7 驱动DAC以及ADC模块之五:nodejs+vue3实现web网页波形显示

前文&#xff1a; petalinux_zynq7 C语言驱动DAC以及ADC模块之一&#xff1a;建立IPhttps://blog.csdn.net/qq_27158179/article/details/136234296petalinux_zynq7 C语言驱动DAC以及ADC模块之二&#xff1a;petalinuxhttps://blog.csdn.net/qq_27158179/article/details/1362…...

Android java中内部类的使用

一.成员内部类 实验1&#xff1a;成员内部类 class Outer {private int a 10;class Inner {public void printInfo(){System.out.println("a "a);}}}public class InnerDemo {public static void main(String args[]) {Outer o new Outer();Outer.Inner i o.new…...

llm的inference(二)

文章目录 Tokenizer分词1.单词分词法2.单字符分词法3.子词分词法BPE(字节对编码&#xff0c;Byte Pair Encoding)WordPieceUnigram Language Model(ULM) embedding的本质推理时的一些指标参考链接 Tokenizer 在使用模型前&#xff0c;都需要将sequence过一遍Tokenizer&#xf…...

pytorch -- torch.nn.Module

基础 torch.nn 是 PyTorch 中用于构建神经网络的模块。nn.Module包含网络各层的定义及forward方法。 在用户自定义神经网络时&#xff0c;需要继承自nn.Module类。通过继承 nn.Module 类&#xff0c;您可以创建自己的神经网络模型&#xff0c;并定义模型的结构和操作。 torch.n…...

Microsoft Edge 越用越慢、超级卡顿?网页B站播放卡顿?

记录10个小妙招 Microsoft Edge 启动缓慢、菜单导航卡顿、浏览响应沉闷&#xff1f;这些情况可能是由于系统资源不足或浏览器没及时更新引起的。接下来&#xff0c;我们将介绍 10 种简单的方法&#xff0c;让 Edge 浏览器的速度重新起飞。 基础检查与问题解决 如果 Microsoft…...

XGB-9: 分类数据

从1.5版本开始&#xff0c;XGBoost Python包为公共测试提供了对分类数据的实验性支持。对于数值数据&#xff0c;切分条件被定义为 v a l u e < t h r e s h o l d value < threshold value<threshold &#xff0c;而对于分类数据&#xff0c;切分的定义取决于是否使用…...

FreeRTOS学习第8篇--同步和互斥操作引子

目录 FreeRTOS学习第8篇--同步和互斥操作引子同步和互斥概念实现同步和互斥的机制PrintTask_Task任务相关代码片段CalcTask_Task任务相关代码片段实验现象本文中使用的测试工程 FreeRTOS学习第8篇–同步和互斥操作引子 本文目标&#xff1a;学习与使用FreeRTOS中的同步和互斥操…...

c++STL容器的使用(vector, list, map, set等),c++STL算法的理解与使用(sort, find, binary_search等)

cSTL容器的使用&#xff08;vector, list, map, set等&#xff09; 在C的STL&#xff08;Standard Template Library&#xff09;中&#xff0c;容器是重要的一部分&#xff0c;它们提供了各种数据结构来存储和管理数据。以下是一些常见的STL容器及其使用方法的简要说明&#x…...

选择VR全景行业,需要了解哪些内容?

近年来&#xff0c;随着虚拟现实、增强现实等技术的持续发展&#xff0c;VR全景消费市场得以稳步扩张。其次&#xff0c;元宇宙行业的高速发展&#xff0c;也在进一步拉动VR全景技术的持续进步&#xff0c;带动VR产业的高质量发展。作为一种战略性的新兴产业&#xff0c;国家和…...

830. 单调栈

Problem: 830. 单调栈 文章目录 思路解题方法复杂度Code 思路 这是一个单调栈的问题。单调栈是一种特殊的栈结构&#xff0c;它的特点是栈中的元素保持单调性。在这个问题中&#xff0c;我们需要找到每个元素左边第一个比它小的元素&#xff0c;这就需要使用到单调递增栈。 我们…...

H5 个人引导页官网型源码

H5 个人引导页官网型源码 源码介绍&#xff1a;源码无后台、无数据库&#xff0c;H5自检测适应、无加密&#xff0c;直接修改可用。 源码含有多选项&#xff0c;多功能。可展示自己站点、团队站点。手机电脑双端。 下载地址&#xff1a; https://www.changyouzuhao.cn/1434.…...

【Linux】部署前后端分离项目---(Nginx自启,负载均衡)

目录 前言 一 Nginx&#xff08;自启动&#xff09; 2.1 Nginx的安装 2.2 设置自启动Nginx 二 Nginx负载均衡tomcat 2.1 准备两个tomcat 2.1.1 复制tomcat 2.1.2 修改server.xml文件 2.1.3 开放端口 2.2 Nginx配置 2.2.1 修改nginx.conf文件 2.2.2 重启Nginx服务 2…...

WPF Style样式设置

1.本window设置样式 <Window x:Class"WPF_Study.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expressi…...

【STM32】软件SPI读写W25Q64芯片

目录 W25Q64模块 W25Q64芯片简介 硬件电路 W25Q64框图 Flash操作注意事项 状态寄存器 ​编辑 指令集 INSTRUCTIONS​编辑 ​编辑 SPI读写W25Q64代码 硬件接线图 MySPI.c MySPI.h W25Q64 W25Q64.c W25Q64.h W25Q64_Ins.h main.c 测试 SPI通信&#xff08;W25…...

普通中小学校管理信息系统V1.1

普通中小学校管理信息系统 Ordinary Primary and Secondary Schools Management Information System 普通中小学校管理信息系统 Ordinary Primary and Secondary Schools Management Information System...

中国水果采摘机器人行业市场研究及发展趋势分析报告

全版价格&#xff1a;壹捌零零 报告版本&#xff1a;下单后会更新至最新版本 交货时间&#xff1a;1-2天 第一章 2016-2026年中国水果采摘机器人行业总概 1.1 中国水果采摘机器人行业发展概述 机器人技术的发展是一个国家高科技水平和工业自动化程度的重要标志和体现。机器…...

Linux多进程与信号

在多进程的服务程序中&#xff0c;如果子进程收到退出信号&#xff0c;子进程自行退出。如果父进程收到退出信号&#xff0c;应该先向全部的子进程发送退出信号&#xff0c;然后自己再退出。 演示demo程序 #include <iostream> // 包含输入输出流库&#xff0c;用于输…...

Self-attention与Word2Vec

Self-attention&#xff08;自注意力&#xff09;和 Word2Vec 是两种不同的词嵌入技术&#xff0c;用于将单词映射到低维向量空间。它们之间的区别&#xff1a; Word2Vec&#xff1a; Word2Vec 是一种传统的词嵌入&#xff08;word embedding&#xff09;方法&#xff0c;旨在为…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

C++--string的模拟实现

一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现&#xff0c;其目的是加强对string的底层了解&#xff0c;以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量&#xff0c;…...

python打卡第47天

昨天代码中注意力热图的部分顺移至今天 知识点回顾&#xff1a; 热力图 作业&#xff1a;对比不同卷积层热图可视化的结果 def visualize_attention_map(model, test_loader, device, class_names, num_samples3):"""可视化模型的注意力热力图&#xff0c;展示模…...

MLP实战二:MLP 实现图像数字多分类

任务 实战&#xff08;二&#xff09;&#xff1a;MLP 实现图像多分类 基于 mnist 数据集&#xff0c;建立 mlp 模型&#xff0c;实现 0-9 数字的十分类 task: 1、实现 mnist 数据载入&#xff0c;可视化图形数字&#xff1b; 2、完成数据预处理&#xff1a;图像数据维度转换与…...