莫队

基础莫队

本质是通过排序优化了普通尺取法的时间复杂度。

考虑如果某一列询问的右端点是递增的,那么我们更新答案的时候,右指针只会从左往右移动,那么i指针的移动次数是$O(n)$的。

当然,我们不可能让左右端点都单调来做到总体$O(n)$。

考虑对左端点进行分块。

莫队排序:

左端点按照分块的编号来排,如果分块编号不同的话编号较小的靠前,如果相同的话右端点小的在前。可以证明这样排完序的话时间复杂度可以做到$O(n \sqrt n)$。

这样我们把区间分成了$\sqrt n$块,每块的长度都是$\sqrt n$,在每一块内部,所有查询的右端点是递增的。

右指针:在每一块内部,右端点递增,所以右端点走的总数不会超过$n$(注意每一块内部放的是左端点,右端点是完全有可能超出这个块的范围的,因此这里为$n$),一共有$\sqrt n$块,所以右端点总共走的次数不会超过$n \sqrt n$。

左指针:先考虑每一次询问:

  1. 左指针在块内部移动,块的长度是$\sqrt n$,因此最多只会移动$\sqrt n$次。

  2. 左指针在相邻两块之间移动,最坏是从第一个块的左端点移动到第二个块的右端点,因此最坏移动$2 \sqrt n$次。

因为有q次询问,所以1是$q \sqrt n$,2是$2n$。

因为一共有$\sqrt n$个块,我们从前往后要跨过$\sqrt n - 1$次,每次最多是$2 \sqrt n$,所以时间复杂度是$2n$。

所以总时间复杂度为$O(q \sqrt n)$。

// 代码为统计一段区间上是否有不相同的数,没有输出yes
int n, q;
int a[N];
vector<array<int, 3>> v;
int cnt[210];
int ans[N];
int len; int get(int x) {
return x / len;
} void adds(int x, int &res) {
if (!cnt[x]) res ++;
cnt[x] ++;
} void del(int x, int &res) {
cnt[x] --;
if (!cnt[x]) res --;
} void solve() {
cin >> n >> q;
len = max(1, (int)sqrt((double)n * n / q));
for (int i = 1; i <= n; i ++) {
cin >> a[i];
a[i] += 100;
}
for (int i = 1; i <= q; i ++) {
int l, r;
cin >> l >> r;
v.push_back({i, l, r});
}
auto cmp = [&](array<int, 3> &a, array<int, 3> &b) {
int i = get(a[1]), j = get(b[1]);
if (i != j) return i < j;
return a[2] < b[2];
};
sort(v.begin(), v.end(), cmp);
// i是右指针,j是左指针
for (int k = 0, i = 0, j = 1, res = 0; k < q; k ++) {
int id = v[k][0], l = v[k][1], r = v[k][2];
while (i < r) adds(a[++ i], res);
while (i > r) del(a[i --], res);
while (j < l) del(a[j ++], res);
while (j > l) adds(a[-- j], res);
ans[id] = res;
}
for (int i = 1; i <= q; i ++)
if (ans[i] == 1) cout << "YES\n";
else cout << "NO\n";
}

莫队算法(基础莫队)小结(也做markdown测试)的更多相关文章

  1. hdu4638 莫队算法

    莫队算法基础题,题目看懂就能做出来 #include<iostream> #include<cstring> #include<cstdio> #include&l ...

  2. Codeforces617 E . XOR and Favorite Number(莫队算法)

    XOR and Favorite Number time limit per test: 4 seconds memory limit per test: 256 megabytes input: s ...

  3. HDU 4358 莫队算法+dfs序+离散化

    Boring counting Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 98304/98304 K (Java/Others)T ...

  4. CSU 1515 Sequence (莫队算法)

    题意:给n个数,m个询问.每个询问是一个区间,求区间内差的绝对值为1的数对数. 题解:先离散化,然后莫队算法.莫队是离线算法,先按按询问左端点排序,在按右端点排序. ps:第一次写莫队,表示挺简单的, ...

  5. XOR and Favorite Number(莫队算法+分块)

    E. XOR and Favorite Number time limit per test 4 seconds memory limit per test 256 megabytes input s ...

  6. 【国家集训队2010】小Z的袜子[莫队算法]

    [莫队算法][国家集训队2010]小Z的袜子 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程, ...

  7. HYSBZ - 2038 小Z的袜子 (莫队算法)

    A1206. 小Z的袜子 时间限制:1.0s   内存限制:512.0MB   总提交次数:744   AC次数:210   平均分:44.44 将本题分享到:        查看未格式化的试题    ...

  8. hdu 5145(莫队算法+逆元)

    NPY and girls Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  9. [BZOJ2038] [2009国家集训队]小Z的袜子(hose) 莫队算法练习

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 10299  Solved: 4685[Sub ...

  10. XIN队算法

    XIN队算法 注:名称由莫队算法改编而来 从luogu搬过来了... \(newly\;upd:2021.7.8\) \(newly\;upd:2021.6.6\) OI至高算法,只要XIN队算法打满 ...

随机推荐

  1. #期望,树的直径#51nod 1803 森林直径

    题目 有一棵 \(n\) 个结点的树,按顺序给出树边 \((fa[i],i)\), \(Q\) 次询问查询如果只选取第 \([l,r]\) 条树边,问森林的直径 \(fa[i]\) 的生成方式为 \( ...

  2. Hessian反序列化分析

    RPC协议 RPC全称为Remote Procedure Call Protocol(远程调用协议),RPC和之前学的RMI十分类似,都是远程调用服务,它们不同之处就是RPC是通过标准的二进制格式来定 ...

  3. Linux-搭建内网yum源

    部署要求: 服务器:CentOS7 YUM源:阿里云 空间要求:CentOS6+CentOS7 50G,考虑后期更新预留,LVS空间100G 1.在服务器配置CentOS7的yum源和CentOS6的 ...

  4. 动态规划(三)——线性dp

    一.概念 具有线性阶段划分的动态规划算法叫作线性动态规划(简称线性DP).若状态包含多个维度,则每个维度都是线性划分的阶段,也属于线性DP,如下图所示: 二.线性dp的三大经典例题 1.LIS问题:求 ...

  5. 重新点亮linux 命令树————内存与文件系统的查看[二十七]

    前言 简单介绍一下内存的查看. 正文 常用命令. free top 查看磁盘使用率: fdisk df du du和ls的区别 free -h 查看内存使用率: free -g 显示按G来显示,-m用 ...

  6. css padding-right没有用?

    前言 问题: 比如说我设置了width为100%了,这个时候我需要padding,但是padding-right似乎没有生效. 正文 原因 实际width=100%容器宽度+padding>容器 ...

  7. CSS:注册页面的编写练习

    最终效果图: html文件: <!-- * @Qusetion: * @Author: 一届书生 * @Date: 2020-04-07 08:17:36 * @LastEditTime: 20 ...

  8. CF1933D Turtle Tenacity: Continual Mods

    思路: 此题其实很简单,不要被邪恶的出题人迷惑了双眼. 此题判断有解一共有两种情况. 通过题意可以知道将原数组排序后如果 \(b_{1} \ne b_{2}\),那么最后的结果一定 \(\ne 0\) ...

  9. 【力扣精选】Oracle SQL 176. 第二高的薪水

    [力扣精选]Oracle SQL 176. 第二高的薪水 这道题很适合用来作为窗口函数的入门使用练习 链接如下: https://leetcode.cn/problems/second-highest ...

  10. 力扣560(java&python)-和为k的子数组(中等)

    题目: 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的连续子数组的个数 . 示例 1: 输入:nums = [1,1,1], k = 2输出:2示例 2: 输入:n ...