首页 > 编程语言 >莫队算法学习笔记

莫队算法学习笔记

时间:2024-02-22 19:58:28浏览次数:22  
标签:询问 笔记 关键字 算法 端点 区间 排序 莫队

普通莫队

形式

假设\(n=m\),那么对于序列上的区间询问问题,如果从\([l,r]\) 的答案能够\(O(1)\) 扩展到 \([l-1,r]\) \([l+1,r]\) \([l,r-1]\) \([l,r+1]\)(即与\([l,r]\) 相邻的区间)的答案,那么可以在\(O(n\sqrt{n})\) 的复杂度内求出所有询问的答案。

实现

离线后排序,顺序处理每个询问,暴力从上一个区间的答案转移到下一个区间答案(一步一步移动即可)。

排序方法

对于\([l,r]\)区间, 以\(r\) 所在块的编号为第一关键字,\(r\)为第二关键字从小到大排序。

return u.l/m==v.l/m?(u.r==v.r?0:((u.l/m)&1)^(u.r<v.r)):u.l<v.l;//奇偶优化

带修莫队(没实现过)

树上莫队

首先,树上莫队就是维护树上的区间关系,嗯

然后就是引入DFN序列,又或者欧拉序,或入栈出栈序(比较倾向最后一种)

就是到某个点时进队列,出某个点时再进一次队列

这里写图片描述

考虑上图中的树,其DFS序为

这里写图片描述

于是,分类讨论(记s[i]为第一个位置,t[i]为第二个位置)

  • u,v在同一条链上,查询区间为[s[u],v[v]]或[s[v],s[u]]
  • 否则,就是查询[t[u],s[v]]或[t[v],s[u]],再加一个lca

然后具体转移时要记录当前某一个点有几个,还没有就直接加,已经有了一个就减掉(删除同理)

于是就变成了普通莫队

回滚莫队

非常简单

就是考虑只能加入或者只能删除

  • 对原序列进行分块,对询问按以左端点所属块编号升序为第一关键字,右端点升序为第二关键字的方式排序。
  • 如果询问左端点所属块 B和上一个询问左端点所属块的不同,那么将莫队区间的左端点初始化为 B的右端点加 1, 将莫队区间的右端点初始化为 B的右端点;
  • 如果询问的左右端点所属的块相同,那么直接扫描区间回答询问;
  • 如果询问的左右端点所属的块不同:
  • 如果询问的右端点大于莫队区间的右端点,那么不断扩展右端点直至莫队区间的右端点等于询问的右端点;
  • 不断扩展莫队区间的左端点直至莫队区间的左端点等于询问的左端点;
  • 回答询问;
  • 撤销莫队区间左端点的改动,使莫队区间的左端点回滚到 B的右端点加 1。

copy oi-wiki的

标签:询问,笔记,关键字,算法,端点,区间,排序,莫队
From: https://www.cnblogs.com/zhy114514/p/18024049

相关文章

  • RabbitMQ 学习笔记
    AMQP协议模型Server:又称为Broker,接受客户端的链接,实现AMQP实体服务Connection:连接,应用程序与Broker的网络连接channel:网络信道,几乎所有的操作都在channel中进行,是消息读写的通道,可建立多个channel,每个channel代表一个会话任务Message:消息本体,由Properties和Body组成,P......
  • 安卓家庭记账本开发笔记7(补2月3日)
    完成收支记录界面的逻辑编写代码如下:packagecom.example.myapplication1;importandroid.os.Bundle;importandroid.view.View;importandroidx.appcompat.app.AppCompatActivity;importandroidx.fragment.app.Fragment;importandroidx.viewpager2.widget.ViewPager2;import......
  • 安卓家庭记账本开发笔记6(补2月2日)
    完成自定义软键盘的绘制和逻辑编写在res文件夹中创建一个文件包命名为xml。在里面创建一个名为key的xml文件,在其中完成自定义软键盘的绘制代码如下:<?xmlversion="1.0"encoding="utf-8"?><Keyboardxmlns:android="http://schemas.android.com/apk/res/android"......
  • 安卓家庭记账本开发笔记5(补2月1日)
    完成自定义软键盘的编写以及软键盘上面的备注和时间在记录页面的代码底下加上下面的代码<android.inputmethodservice.KeyboardViewandroid:id="@+id/frag_record_keyboard"android:layout_width="match_parent"android:layout_height="wrap_content"......
  • 【图论】基环树 学习笔记
    基环树下面几个条件互相等价:一个图(连通块)是基环树联通块有n个点n条边图上存在且仅存在一个环,且环上每个节点是一颗子树的根。通常情况下树指的都是无向图,但是有向图也可以构成基环树。内向基环树:每个点都有一条出边。容易发现沿着这条边一定会走到环上“向内走”。外......
  • Vue学习笔记11--事件
    示例一:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Vue事件的基本使用</tit......
  • 代码随想录算法训练营第二十五天| 216.组合总和III 17.电话号码的字母组合
    组合总和III题目链接:216.组合总和III-力扣(LeetCode)思路:仿照昨天的递归模板写的,同样是for循环横向遍历,递归纵向遍历。注意当k>n时要直接跳出,否则会判断栈溢出。额外发现一个问题就是在累加sum时,用for(autoi:path)sum+=path[i];会出现奇怪数字,原因是auto遍历用法错误,正确写......
  • 概率与期望学习笔记(copy)
    概率&期望样本空间、随机事件定义一个随机现象中可能发生的不能再细分的结果被称为样本点。所有样本点的集合称为样本空间,通常用\(\Omega\)来表示。一个随机事件是样本空间\(\Omega\)的子集,它由若干样本点构成,用大写字母\(A,B,C,\cdots\)表示。对于一个随机现......
  • DFS算法模板(2488:A Knight's Journey)
    DFS算法(C++版本)题目一:链接:http://bailian.openjudge.cn/practice/2488/解析思路:骑士找路就是基本的DFS,用递归不断找到合适的路,找不到就回头直到找到合适的路。该题难点:要是实现字典序,也就是同样的两种选择,要走到A1而不是B1。所以就有了{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1......
  • Python笔记11——函数
    十一、函数函数的作用:提高模块化程度,提高代码重复利用率。11.1定义一个函数一般格式:def函数名(参数列表):函数体以def关键字开头,后接函数标识符名称和圆括号()。所需参数必须都在圆括号中声明。(默认参数值和参数名称是按函数声明中定义的顺序匹配起来的。)函数内容以......