首页 > 其他分享 >杂:某两道依赖数组长度为 2^{k} 的杂题

杂:某两道依赖数组长度为 2^{k} 的杂题

时间:2024-09-29 14:02:03浏览次数:7  
标签:lfloor frac rfloor cdots 数组 区间 长度 杂题 两道

问题 1:

给定序列 \(a_0, a_1, a_2, \cdots, a_n\) 满足 \(n - 1 = 2^{k} (k \geq 0)\) 。定义 \(R_{i}\) 为 \(i\) 的 \(k\) 位的无符号二进制反转。

输出 \(a_{R_{0}}, a_{R_{1}}, a_{R_{2}}, \cdots, a_{R_{n - 1}}\) 。

题解:

首先考虑如何得到 \(R_{i}\) 。对二进制下标使用微扰法,注意到:

\[\begin{aligned} &\lfloor \frac{ R_{\lfloor \frac{i}{2}} \rfloor }{2} \rfloor = R_{i} \odot (2^{n - 1} - 1) \\ \Rightarrow &R_{i} = \lfloor \frac{ R_{\lfloor \frac{i}{2}} \rfloor }{2} \rfloor | ( (i \odot 1) \times 2^{n - 1} ) \end{aligned} \]

其次考虑如何让 \(a_0, a_1, a_2, \cdots, a_{n - 1}\) 变成 \(a_{R_{0}}, a_{R_{1}}, a_{R_{2}}, \cdots, a_{R_{n - 1}}\) 。注意到序列分解成了 \(\frac{n - 1}{2}\) 个循环群,每个群为 \((i, R_{i})\) ,只需循环移位一次。\(for \ i \ = 0 \to \frac{n - 1}{2}\) \(swap(a[i], a[R[i]])\) 即实现。

问题 2:

考虑对 \(0, 1, 2, \cdots, n\) 满足 \(n - 1 = 2^{k} (k \geq 0)\) 的数轴二分分治。对分治的每个区间 \(l, r\) 需要使用指针 \(i, j\) 分别指向起点和中点开始并行右移。做出非递归版本的代码实现。

题解:

代码实现如下。

for (int m = 2; m < n; m *= 2) {
	for (int l = 0; l + m - 1 < n; l += m) {
		for (int i = l, j = l + m / 2; i < l + m / 2; i++, j++) {
			
		}
	}
}
  1. 问题的关键在于先考虑从小到大枚举区间长度。从最小非叶子区间长度 \(m = 2\) ,枚举到根的区间长度 \(n - 1\) ,每次区间长度会乘以 \(2\) 。
  2. 其次在于枚举每个区间的左端点 \(l\) ,下一个区间的端点为 \(l + m\) ,需要保证右端点不超过 \(n - 1\) 即 \(l + m - 1 < n\) 。
  3. 最后是对每个区间操作,显然不难是并行指针 \(i, j\) 分别指向 \(l\) 和中点 \(l + m / 2\) ,保证左指针不超过中点或右指针不超过右端点即可。

标签:lfloor,frac,rfloor,cdots,数组,区间,长度,杂题,两道
From: https://www.cnblogs.com/zsxuan/p/18439498

相关文章

  • P10589 楼兰图腾(树状数组)
    #include<bits/stdc++.h>usingnamespacestd;#definexfirst#defineysecondtypedefpair<int,int>PII;typedeflonglongll;typedefunsignedlonglongull;typedefunsignedintuint;typedefvector<string>VS;typedefvector<int>......
  • JS数组指针prev、current、next的实现方式,涉及是否删除当前元素的情况分析
    背景由于业务,需要做一个循环切换的轮播图效果,循环展示列表中的每个item,但是由于切换(从左往右移动,遇到末尾则跳到开头)的过程中可能会删掉当前元素,所以需要更新下标后再切换。由于涉及到几个临界条件,这里列出来处理方式,以便后续参考。代码这里给出的简化过后的代码:<template>......
  • 【AHK】打造炒股利器系列——用数组和循环来简化语音报时器
    上一篇文章,【AHK】打造炒股利器系列——语音报时器作为AHK入门,讲解了注释、赋值、if语句、逻辑运算符、定时器等基本知识。本篇将引入Array和Loop语句来简化化这个语音报时器,让代码更优雅,代码越简单越不容易出错误,老话说秃头上的虱子明摆着嘛。简化说明:我们用两个数组......
  • 算法训练营第二天| 209.长度最小的子数组、59.螺旋矩阵II
    209.长度最小的子数组状态:没写出来->确认自己的想法是对的之后写出来了!!!初始思路:因为子数组是连续的,所以可以采用滑动窗口,我把这个窗口设置为左闭右闭,所以初始左右边界为0。之后先移动右指针,使得找到第一个和大于等于target的子数组,记录其长度,之后再移动左指针一位,再找第二个......
  • javascript 数组对象解构
    传统的写法不好记忆,书写麻烦,此时可以使用结构赋值的方法让代码更加简洁。数组结构是将数组中的单元值快速批量赋值给一系列变量的简介语法。变量的顺序对应数组单元值位置一次进行赋值操作。如下:应用一:交换两个变量Js前面有那种情况需要加分号。(不加分号解析器认为和上......
  • rust交换数组中的两个元素
    不可以直接用std::mem::swap,因为这个函数需要拿两个可变引用,但是不可以同时拿两个这个数组的可变引用。所以要么手写:lettmp=a[i];a[i]=a[j];a[j]=tmp;要么用Vec::swap:a.swap(i,j);其内部实现:fnswap(&mutself,a:usize,b:usize){unsafe{//......
  • 二维数组的创建和初始化
    1.二维数组的概念按我的理解,其实二数组就是有多个一维数组组成的,多个二维数组作为元素,那就是三维数组,多个三维数组就是多维数组。2.二维数组的创建1.type arr_name[常量值1 ][常量值2 ]={};2.例如:3.intarr[3][6];4.doubledata[4][6];1.type代表类型2.arr表示数......
  • 代码随想录算法训练营第二天| 209.长度最小的子数组、59.螺旋矩阵II 、区间和、开发
    209.长度最小的子数组此题注重理解,同时我将res一开始初始化为sums的长度加一(因为不可能为此长度)INT32_MAX是一个常量,代表32位有符号整数的最大值classSolution{public:intminSubArrayLen(inttarget,vector<int>&nums){inti=0,j=0;//i为起始位置,j为......
  • C++字符串与字符数组
    在C++中,字符串和字符数组是紧密相关的概念,但它们之间也存在一些关键的区别。理解这些区别对于编写高效、安全的C++代码非常重要。字符数组字符数组是C++中用于存储字符序列的基础数据结构。它本质上是一个元素类型为char的数组,可以在声明时初始化,也可以在运行时通过赋值或函......
  • 数组
    文章目录数组的概念⼀维数组的创建和初始化数组创建数组的初始化数组的类型⼀维数组的使用·数组下标数组元素的打印数组的输入⼀维数组在内存中的存储sizeof计算数组元素个数⼆维数组的创建⼆维数组的概念⼆维数组的创建⼆维数组的初始化不完全初始化完全初始化按照......