首页 > 其他分享 >块状数据结构选做

块状数据结构选做

时间:2023-06-17 09:02:26浏览次数:39  
标签:cnt 选做 复杂度 个数 sqrt 块状 数值 mathcal 数据结构

收集了最近做的一些块状数据结构题,涉及分块,莫队,块状链表等,难度大多不是很高,老少皆宜。 QAQ

P4168 [Violet]蒲公英

题目链接

大意:静态在线区间众数

先离散化,预处理出 \(cnt_{i,j}\) 和 \(mode_{i,j}\),分别表示前 \(i\) 块中数值 \(j\) 出现的次数和第 \(i\) 到第 \(j\) 块的众数。可以 \(\mathcal{O}(n\sqrt{n})\) 实现(\(mode_{i,j+1}\) 可由 \(mode_{i,j}\) 在 \(\mathcal{O}(\sqrt{n})\) 的时间内推出)。

对于每次查询,答案要么在散块,要么在整块。只需扫描散块的所有数,判断其是否可以更新答案即可。

时间复杂度 \(\mathcal{O}((n+m)\sqrt{n})\)。

参考代码链接

P4135 作诗

题目链接

大意:静态在线区间出现正偶数次的数值的个数

先分享一个我的奇怪做法,

显然,\(出现正偶数次的数值的个数 = 区间数值个数 - 出现奇数次数值的个数\),

区间数值个数主席树很好做,我们考虑如何处理出现奇数次数值的个数,

用 \(cnt_i\) 表示 \(i\) 出现的次数,如果暴力计算,每逢一个数 \(v\),就让 \(cnt_v\) 加一,那么只要统计 \(cnt\) 中的奇数的值的数量即可,

我们让 \(cnt_i\) 的值模 2,可以发现,加一就相当于 \(cnt_v=cnt_v ~\texttt{xor}~1\)。

于是思路就很明显了,对序列分块,设块长为 \(T\),预处理 \(\mathcal{O}(\dfrac{n}{T})\) 个 \(\texttt{bitset}\) 对于第 \(i\) 个 \(\texttt{bitset}~cnt_i\),存储第 1 到第 \(i\) 块末尾这些数按上面的方式做出的结果 (即 \(cnt_{i,j}\) 表示前 \(i\) 块中数值 \(j\) 出现次数的奇偶性),这个东西是前缀可减的(\(cnt_{p,j}~\texttt{xor}~cnt_{q,j}\) 表示第 \(p\) 到 第 \(q\) 块数值 \(j\) 出现次数的奇偶性),加上散块暴力,单次询问复杂度为 \(\mathcal{O}(\dfrac{n}{w}+T+\log n)\) (假设 \(n\) 与值域同阶, \(\log\) 为主席树复杂度)。

对于预处理,每个块分别预处理,然后做一个前缀 \(\texttt{bitset}\) 异或即可,预处理时间复杂度 \(\mathcal{O}(\dfrac{n^2}{Tw})\)。

总的时间复杂度就是 \(\mathcal{O}(\dfrac{n^2}{Tw}+m(\dfrac{n}{w}+T+\log n))\),由均值不等式,取 \(T=\dfrac{n}{\sqrt{mw}}\) 即可取到理论最优复杂度。(实际调块长很玄学QAQ)

可通过本题,但是我的写法跑的不快awa

参考代码链接

下面分享一下正宗 \(\mathcal{O}(n\sqrt{n})\) 做法

预处理出数组 \(s_{i,j}\),表示第 \(i\) 到第 \(j\) 块这些整块的答案,可以 \(\mathcal{O}(n\sqrt{n})\) 实现。

对于每组询问,扫描散块的数,计算对答案的影响即可,实现的时候有些细节要注意。

参考代码链接

P4396 [AHOI2013]作业

题目链接

题目大意:静态询问区间值在 [a,b] 内的数的个数和数值的个数

考虑莫队,指针总共移动 \(\mathcal{O}(n\sqrt{m})\) 次,查询答案 \(\mathcal{O}(m)\) 次,因此我们需要一个 \(\mathcal{O}(1)\) 修改,\(\mathcal{O}(\sqrt{n})\) 查询的数据结构。我们只需要对值域分块即可,维护每个块内数值的个数和数的个数,查询的时候散块暴力查询,整块直接加上标记就可以了。

时间复杂度 \(\mathcal{O}(n\sqrt{m}+m\sqrt{n})\)。调一下块长跑得飞快。

参考代码链接

P9410 『STA - R2』机场修建

题目链接

大意:要求数据结构支持联通块合并、编号在区间 [a,b] 内的点点权加、查询联通块点权和

维护数组 \(cnt_{i,j}\) 记录并查集代表元为 \(i\) 的联通块在第 \(j\) 块的个数。每个并查集再维护一个 \(sum\),表示散块暴力加上的点权。

对于区间加,整块打上 tag,散块暴力加到对应并查集的 \(sum\) 上。

合并直接做即可。

对于查询代表元为 \(t\) 的并查集,第 \(i\) 个整块的贡献就是 \(tag_i \times cnt_{t,i}\),\(\mathcal{O}(\sqrt{n})\)计算即可,最后加上 \(sum_t\)。

时间复杂度 \(\mathcal{O}(n\sqrt{n})\),空间复杂度 \(\mathcal{O}(n\sqrt{n})\)。

这道题空间限制比较紧,但是卡一卡就能过去(也可以把 \(cnt\) 搞成 \(\texttt{vector}\),进而空间复杂度线性,但是我的写法时间复杂度要带个二分的 \(\log\))

参考代码链接

动态数组版

还没有写完qwq

标签:cnt,选做,复杂度,个数,sqrt,块状,数值,mathcal,数据结构
From: https://www.cnblogs.com/FreshOrange/p/17486992.html

相关文章

  • 数据结构(Python版)——3、基本结构
    数据结构(Python版)——3、基本结构什么是线性结构LinearStructure线性结构是一种有序数据项的集合,其中每个数据项都有唯一的前驱和后继除了第一个没有前驱,最后一个没有后继新的数据项加入到数据集中是,只会加入到原有某个数据项之前或之后具有这种性质的数据集,就称为线性结构......
  • 2023-06-15:说一说Redis的Key和Value的数据结构组织?
    2023-06-15:说一说Redis的Key和Value的数据结构组织?答案2023-06-15:全局哈希表Redis使用哈希表作为保存键值对的数据结构,通过哈希函数将Key映射为哈希表中的一个索引位置,使得Key-Value可以在O(1)时间复杂度内被快速访问。在Redis中,哈希表是由多个哈希桶(也称为槽位/数组元素)组成......
  • C/C++《数据结构》课程设计指导书[2023-06-15]
    C/C++《数据结构》课程设计指导书[2023-06-15]《数据结构》课程设计指导书适用专业:计算机2022级编写人:李玉龙2023年5月《数据结构》课程设计指导书一、设计目的1、训练学生灵活应用所学数据结构知识,独立完成问题分析,结合数据结构理论知识,编写程序求解指定问题;2.初步掌握软......
  • 数据结构(python版)—— 2、前期知识与算法分析
    从C转到python(一)C:helloWorld!#include<stdio.h>​intmain(){//sayhelloprintf("HelloWorld!\n")}1-Compile编译到机器码2-Link与各种库链接3-Execute执行目标程序Python:HelloWorld!defmain():#sayhelloprint("HelloWorld!"......
  • 数据结构的基线和更新
    问题SQLSession是一个非常大的内存结构,一个分布式执行的Query中,SQLSession要被复制/序列化多次,复制开销非常大。如果有机会再来一遍,如何设计SQLSession才能避免这种开销呢?思路下面提出一种思路:对于不变、可共享的数据,设计成只读结构,无需拷贝/序列化,支持多线程并发读。对于可......
  • 【数据结构】部分易考知识点回顾
    期末实验考试一共线性表、树和查找、图、排序四道题。据说需要重点复习二叉树的遍历与哈希表。目前还没写完,龟速更新中。。。线性表&栈&队列顺序栈表达式求值核心逻辑核心算法是一个循环,每次读入一个元素:可能是一个数或一个符号(运算符、左右括号和结束符)括号包着的是一......
  • python基础知识——内置数据结构(集合)
    python中的set是指一系列无序元素的集合,其中的元素都是相异的,常见的操作包括集合的并集,交集和补集等操作。1、set的创建格式set_name={value1,value2,...}创建空的集合set_name=set()注意:在创建空的集合的时候不能使用set_name={}这样创建出来的是字典。例如animals......
  • 挑战数据结构和算法面试题——最大间隔
    分析:本题首先需要理解清楚最大间隔的最小:最初的间隔为:[1,1,4,1],此时最大间隔为4删除2后的间隔为:[2,4,1],此时最大间隔为4删除3后的间隔为:[1,5,1],此时最大间隔为5删除7后的间隔为:[1,1,5],此时最大间隔为5在删除元素后的间隔为:[4,5,5],最小值为:4方法:intget_min_max_margin(int*a,constintn){......
  • 挑战数据结构和算法——栈的push、pop序列
    题目来源“数据结构与算法面试题80道”。在此给出我的解法,如你有更好的解法,欢迎留言。问题分析:本题考查栈的基本操作,栈是一种“先进后出”的数据结构。判断一个序列是否是栈的pop序列是一种常见的问题,可以通过模拟push和pop的过程,push和pop总是成对出现的,如:方法:#definepush1#def......
  • 【数据结构和算法面试题】跳台阶问题
    题目来源“数据结构与算法面试题80道”。问题分析:假设为跳台阶的总跳法,当时,;当时,;当时,如果先跳1级台阶,有种方法,如果先跳2级台阶,有种方法,依次类推,可以得到下面的递推公式:方法:intget_kind(intn){ if(n<=0)return0; intresult; int*cal=(int*)malloc(sizeof(int)*n);......