范围修改查询问题

news/2025/1/26 17:43:43/文章来源:https://www.cnblogs.com/konyakest/p/18692020

范围修改查询问题

http://www.nfls.com.cn:10611/up/paper/国家集训队2024论文集.pdf P63

引入

这部分作者定义了半群和幺半群来描述一般的线段树可以做到的结构

  • 半群:结合律

  • 幺半群:结合律、有幺元

  • 交换半群:结合律、交换律

形式化问题:(以下是通俗易懂的版本)

  • 给定交换半群 \(D\)(“数据”)和半群 \(M\)(“标记”),数据经过两次标记的操作可以转化为数据经过(两次标记复合得到的标记)的操作,标记对数据的加法有分配律。要求支持范围打标记范围求和

以下称“范围打标记”为 apply,范围求和为 accumulate

最优离线范围修改查询算法

算法

问题:给定点集的划分方式 \(f_i\)\(f_i\) 是点集集合),\(n\) 次操作,每次操作为:

  • \(p\in f_i\) 的所有点 \(p\) apply

  • \(p\in f_i\) 的所有点 \(p\) accumulate

一个 \(f_i\) 的集合 \(\{f_1,f_2,\cdots\}\) 会将点集划分为若干等价类

我们用森林结构刻画等价类。每个树对应等价类。两个等价类的合并即为:新建一个节点,然后将这两棵树的根节点设为这个节点的儿子

考虑分治。初始时我们有点集经过询问 \([1,q]\) 的划分方式 \(P_{1,q}\)。当我们知道 \(P_{l,r}\) 时,我们可以:

  • 合并 \([mid+1,r]\)

  • 递归 \(P_{1,mid}\)

  • 撤销合并,并合并 \([l,mid]\)

  • 递归 \(P_{mid+1,r}\)

到叶子节点的时候,我们想要的那个划分一定是一棵树,在这棵树上 applyaccumulate 即可

在合适的时刻需要 push_up 或者 push_down

复杂度

\(P(n)\) 表示 \(n\) 个划分可以把点集划分为多少个区域,则 \(T(n)=T({n\over 2})+P(n)\)

设有 \(n\) 个点 \(m\) 次询问,执行一次算法的复杂度为 \(O(n)+T(m)\)

当划分为线段时,\(P(n)=O(n)\),则复杂度为 \(O(n+m\log m)\)

当划分为二维曲线,如圆、椭圆、凸多边形、双曲线,复杂度为 \(O(n+m^2)\)。考虑每 \(\sqrt\) 个点运用上述算法即可平衡到 \(O(n+m\sqrt n)\)

\(d\) 维空间范围为 \(O(n+mn^{1-{1\over d}})\)

例:半平面修改查询

使用以上算法。考虑如何找到划分

首先初始时的划分可以通过扫描线找到:对于 \(O(B)\) 条线,两两求出交点,然后按照一维扫描线,维护线的顺序

扫描线的过程中可能会出现线顺序交换的情况,维护即可

每一条线上开一个链表挂上这条线的交点

合并的时候,找到这条线合并即可,需要更新链表

单点查询

单点查询的时候,我们可以只维护划分方式,只要查询的时候可以快速定位到区域即可

例:P7881

先考虑不强制在线的做法

\(B\) 个操作分块

使用二维数组刻画划分方式,我们有 \(O({n\over B})\) 个二维数组

每次查询的时候在整块的二维数组中二分得到对应答案,散块直接暴力

当强制在线的时候,我们把散块暴力改为二进制分组即可。显然这个结构支持合并,我们只需要重新排序即可

半平面范围查询

半平面范围上的划分有若干形式

注:以下为静态查询问题

数据随机算法

KDT

直接 KDT 的复杂度是错的,但是在数据随机的时候可以使用

平面分块

\(\sqrt n\times \sqrt n\) 个区域分成一块,每个块期望 \(O(1)\) 个点

枚举每一个横行,整块是每个横行的前缀或后缀,散块暴力统计

是效率最高的算法

例题

  • uoj 533

式子转化后发现是半平面数点

  • P8261

半平面颜色平方和

考虑 KDT

首先,把询问和修改反演,通过式子变形转化为这样的问题:

给定若干半平面,每个半平面有颜色,对于一个询问的点求包含它的半平面的颜色平方和

考虑这个问题的序列版本怎么做:对于每个颜色,设出现次数为 \(cnt_c\),把区间离散化,则会分为 \(O(cnt_c)\) 段,每段单独修改即可

如果在线段树上,则可以给每个节点一个 \(tot\),每次对应节点的子树打 \(tot\leftarrow tot+1\) 的标记,把该颜色的这种操作做完后,枚举所有访问过的虚树的叶子节点,给这些节点的子树进行修改

在 KDT 上做以上过程即可

  • P9996

旋转扫描线

定义一个半平面的“标准型”为:先向下移动半平面直到碰到点,然后旋转半平面直到碰到点

显然 \(O(B)\) 个点只有 \(O(B^2)\) 种半平面的标准型

于是我们证明了 \(O(B)\) 个点只有 \(O(B^2)\) 种半平面划分方式

随机一个点作为原点,然后枚举斜率进行旋转,此时我们在讨论一条线绕着一个点旋转的动态过程

考虑每个点到这条线的投影,这些投影的顺序变化只会发生 \(O(B^2)\)

枚举两两连线即可找到变化的时机,共 \(O(B^2)\) 个,把变化挂在对应时机上

在对应的时机查询即可。数据结构只需要支持交换相邻元素,查询前缀或后缀。可以 \(O(1)\) 维护

半平面莫队

P8529

维护点集,使用 \(O(n\sqrt n)\) 次操作,每次加点、删点,使得每一个半平面区域都至少出现一次

随机选取 \(O(B)\) 个点,旋转扫描线,在斜率时刻暴力移动截距,这部分 \(O(n\sqrt n)\)

我们把一个半平面挂在截距最小的那个原点上,则每个半平面期望移动 \(O(\sqrt n)\)

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

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

相关文章

实现超图S3M数据在Ceisum中的解析、加载

使用超图提供的S3M加载模块。参考文档:S3M_JS使用方法 1. 将项目的Cesium库的Build目录及其内容放在S3M_JS目录中,与S3M_module同级。2. 调用该模块解析、加载S3M数据 const layer = new S3MTilesLayer({context: window.viewer.scene._context,url }) window.viewer.scene.p…

Beyond Compare(文件比较工具) v5.0.5.30614 多语便携版

Beyond Compare是一款功能强大的文件和文件夹比较工具,它能够快速准确地比较文件之间的差异,并提供了一系列强大的功能和工具来帮助用户进行文件和文件夹的同步、合并和备份。 软件功能 - 文件和文件夹比较:Beyond Compare能够快速准确地比较两个文件或文件夹之间的差异,包…

使用EarTrumpet代替windows默认的音量调节功能

前言 https://github.com/File-New-Project/EarTrumpet Windows 默认的音量调节功能挺弱的,要分别调节各个应用的音量得进入二级菜单,麻烦得很 有了这个功能就很方便了 截图安装 老规矩,Github、Microsoft Store、choco、scoop都行 我选的是 scoop 扩展:替换系统的音量控制…

JS-43 document对象_方法/创建元素

document创建元素:createElement(创建元素)createTextNode(创建元素文本)createAttribute(创建元素的属性) 1、document.createElement()document.createElement方法用来生成元素节点,并返回该节点var newDiv=document.createElement(div); 2、document.createTextNode()…

Keydd : 流量包匹配敏感信息的工具

免责声明 工具仅供安全研究与学习之用,若将工具做其他用途,由使用者承担全部法律及连带责任,作者及发布者不承担任何法律及连带责任。信息及工具收集于互联网,真实性及安全性自测!!!​ 项目介绍 一直在使用一些工具插件,来检测流量中的ak、sk、sfz、敏感信息,但是网上…

使用twinkle-tray快捷调整多个显示器的亮度

前言 自从安装了这个小工具,我再也没用过笔记本键盘上的快捷键了~ 介绍Twinkle Tray enables brightness control on external displays in Windows 10 & 11. Even though Windows is capable of adjusting the backlight on most monitors, it doesnt support external m…

ACM寒假集训第二次作业

二分查找 思路 运用二分查找,逐渐逼近所要查找的数字 代码 #include<iostream> using namespace std; int binary_search(int arr[],int l,int r,int x){int mid;while(l<r){mid=(l+r)>>1;if(arr[mid]>=x) r=mid;else l=mid+1;}return arr[l]; }; int main(…

【Java安全】保护Java应用程序:如何嗅探JVM的变量

在这篇文章中,我们回顾如何嗅探JVM的变量可能的方法。这篇文章的主要目的是解释如何保护你的应用程序。计划是进行下一步的攻击。从Dump中读取敏感数据。通过在外部依赖中注入恶意软件来窃取源代码。从Java Dump中窃取数据, 如果有人获得了对Java进程的访问权,他可能会读取敏…

第二讲 二分法

第一题 二分查找 输入一个整数 n 和 n 个整数,保证这 n个整数已经按照从小到大进行排序。 然后输入一个整数 q( q≤100000)代表 q次查询。接下来 q 行,每行含有一个整数 m ,代表一次查询。对于每次查询,使用二分查找判断 m 是否在之前输入的 n个整数中出现过。如果出现,…

draw.io(免费流程图制作工具) v26.0.7 中文绿色版

draw.io是一款免费的在线图表绘制工具,它提供了强大的功能和易于使用的界面,适用于各种绘图需求。 软件功能 1. 多种类型的图表:draw.io支持创建各种类型的图表,包括流程图、组织结构图、UML图、网络拓扑图、平面图等。2. 自定义图表元素:用户可以根据自己的需求,自定义…

Svelte 最新中文文档翻译(6)—— if、each、key、await 逻辑区块

前言 Svelte,一个非常“有趣”、用起来“很爽”的前端框架。从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1:Svelte 以其独特的编译时优化机制著称,具有轻量级、高性能、易上手等特性,非常适合构…

java中的集合ArrayList

创建集合对象有3种形式 1,不需要传递构造参数,直接new就可以,此时底层数组为空数组。 2,构造参数需要传递一个int类型的值, 用于设置底层数组的长度 3,构造参数需要传递一个Collection集合类型的值,用于将集合中的数据放置在当前的集合中。 第1种方式创建数组 package goodSt…