小Z的袜子 & 莫队
莫队学习 & 小Z的袜子
引入
莫队 由莫涛巨佬提出,是一种离线算法 运用广泛
可以解决广大的离线区间询问题
莫队的历史
早在mt巨佬提出莫队之前 类似莫队的算法和莫队的思想已在Codeforces
的高手圈中小范围的流传 但mt是首位对莫队进行具体归纳总结的人
经过OIer和ACMer的改造 延伸出了许多扩展莫队 如 回滚莫队
可是俺只会普通莫队 这个坑还是以后再填吧(逃)
经典

学习
蒟蒻的我:莫队长啥样
见到mt本人就知道了
区间\([l,r]\)可以在\(O(1)\)的时间里求出相邻区间的贡献
即\([l,r + 1]\),\([l + 1,r]\),\([l - 1,r]\),\([l,r - 1]\)
那么你就可以在\(O(n \sqrt n)\)的时间里解决问题
思路
我们维护两个指针\(l和r\)在数组上跳来跳去
但若只是如此 那么莫队是无法焕发容光的
你会发现 若按读入的顺序跳来跳去 那么就会非常的Crazy
而且复杂度最高就爆掉了 达到了惊人de\(O(n^2)\)
对于莫队的题 出题人不可能让你过的 (除非数据过水
那么我们需要一个精美绝伦的\(std::sort\)让它跳得近一些
这样就可以有效地减少重复跳跃的路径
于是就变成了离线(没听说过有在线的莫队
莫队就大概是这样了吧
例题 & 实现
小Z的袜子
莫队的板子 竟然是当年的国家集训队
可见莫队的用处还是挺大的 况且NOI大纲上莫队好像是提高组的(没看过awa
对于区间\([l,r]\)内
每种颜色的袜子的贡献为\(sum[col[x]] * (sum[col[x]] - 1)\)
其中sum[i]表示颜色为i的袜子的数量 (当前区间\([l,r]\))
那么我们就有了如下更新
void revise(int x, int v) {ans -= sqr(sum[col[x]]), sum[col[x]] += v, ans += sqr(sum[col[x]]);}
对于之前的莫队形式 我们用\([l,r]\)做如下的更新
while(l < Katze[i].l) revise(l, -1), ++l;
while(l > Katze[i].l) revise(l - 1, 1), --l;
while(r < Katze[i].r) revise(r + 1, 1), ++r;
while(r > Katze[i].r) revise(r, -1), --r;
这时候我们算一下复杂度并且构造一下那个美妙绝伦的\(std::sort\)
我们将询问分块 设块的大小为\(size\)
分类讨论一下
l和下一次询问的l不在同一块内 需要至多\(2 \times size\)次移动 共有\(m\)次询问 时间复杂度为\(O(m \times size)\)
l和下一次询问的l在同一块内 最好的情况(可控)就是$O(\frac{n ^ 2}{size}) $具体如下
当l所在块相同时才会有序 此时我们在l所在块相同的时候按排序那么我们就可以把sort写成这样
struct Feder_der_Katze{
	int l, r, id;
	int ans1, ans2;
	friend bool operator < (const Feder_der_Katze a, const Feder_der_Katze b) {
		if (bel[a.l] == bel[b.l]) return a.r < b.r;
		else return a.l < b.l;
	}
}Katze[N];
bool compare(Feder_der_Katze a, Feder_der_Katze b) {
	return a.id < b.id;
}
那么我们跑一个块r最多跳\(O(n)\)次 总复杂度就是\(O(\frac{n ^ 2}{size})\)
综上所述 复杂度应该是\(O(n\sqrt n + \frac{n^2}{size})\)
根据不等式的知识来讲 大约在\(size = sqrt(n)\)也是一般情况下最优
总的时间复杂度\(大常数C * O(n\sqrt n) = O(跑得过)\)
温馨提示
本题中注意事项:
询问的\(l = r\)需要特判
写sort的时候是\(l所属的块相等时判r 不一定是l相等\)
别问怎么知道的 不会Wrong Answer但会Time Limit Exceeded$

Code
#include <bits/stdc++.h>
using namespace std;
int read(int x = 0, bool f = false, char ch = getchar()) {
	for (; !isdigit(ch); ch = getchar()) f |= (ch == '-');
	for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
	return f ? ~x + 1 : x;
}
const int N = 5e4 + 5;
int n, m, siz, ans;
int col[N], bel[N], sum[N];
struct Feder_der_Katze{
	int l, r, id;
	int ans1, ans2;
	friend bool operator < (const Feder_der_Katze a, const Feder_der_Katze b) {
		if (bel[a.l] == bel[b.l]) return a.r < b.r;
		else return a.l < b.l;
	}
}Katze[N];
bool compare(Feder_der_Katze a, Feder_der_Katze b) {
	return a.id < b.id;
}
int gcd(int x, int y) {return !y ? x : gcd(y, x % y);}
int sqr(int x) {return x * x;}
void revise(int x, int v) {ans -= sqr(sum[col[x]]), sum[col[x]] += v, ans += sqr(sum[col[x]]);}
signed main() {
	n = read(), m = read(), siz = sqrt(n);
	for (int i = 1; i <= n; ++i) col[i] = read(), bel[i] = i / siz + 1;
	for (int i = 1; i <= m; ++i) Katze[i].l = read(), Katze[i].r = read(), Katze[i].id = i;
	sort(Katze + 1, Katze + 1 + m); int l = 1, r = 0;
	for (int i = 1; i <= m; ++i) {
		while(l < Katze[i].l) revise(l, -1), ++l;
		while(l > Katze[i].l) revise(l - 1, 1), --l;
		while(r < Katze[i].r) revise(r + 1, 1), ++r;
		while(r > Katze[i].r) revise(r, -1), --r;
		if (Katze[i].l == Katze[i].r) {Katze[i].ans1 = 0, Katze[i].ans2 = 1; continue;}
		Katze[i].ans1 = ans - (Katze[i].r - Katze[i].l + 1);
		Katze[i].ans2 = (Katze[i].r - Katze[i].l + 1) * (Katze[i].r - Katze[i].l);
		int Gcd = gcd(Katze[i].ans1, Katze[i].ans2);
		Katze[i].ans1 /= Gcd, Katze[i].ans2 /= Gcd;
	} sort(Katze + 1, Katze + 1 + m, compare);
	for (int i = 1; i <= m; ++i) printf("%d/%d\n", Katze[i].ans1, Katze[i].ans2);
	return 0;
}
												
											小Z的袜子 & 莫队的更多相关文章
- BZOJ 2038 [2009国家集训队]小Z的袜子 莫队
		
2038: [2009国家集训队]小Z的袜子(hose) 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=2038 Descriptionw ...
 - 【国家集训队2010】小Z的袜子[莫队算法]
		
[莫队算法][国家集训队2010]小Z的袜子 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程, ...
 - bzoj 2308 小Z的袜子(莫队算法)
		
小Z的袜子 [题目链接]小Z的袜子 [题目类型]莫队算法 &题解: 莫队算法第一题吧,建议先看这个理解算法,之后在参考这个就可以写出简洁的代码 我的比第2个少了一次sort,他的跑了1600m ...
 - P1494 [国家集训队]小Z的袜子/莫队学习笔记(误
		
P1494 [国家集训队]小Z的袜子 题目描述 作为一个生活散漫的人,小\(Z\)每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小\(Z\)再也无法忍受这恼人的找袜子过程,于是他 ...
 - BZOJ 2038 小z的袜子 & 莫队算法(不就是个暴力么..)
		
题意: 给一段序列,询问一个区间,求出区间中.....woc! 贴原题! 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过 ...
 - BZOJ2038 [2009国家集训队]小Z的袜子  莫队+分块
		
作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… 具体来说,小Z把这N只袜子从1到N编号,然后从 ...
 - Luogu 1494 - 小Z的袜子 - [莫队算法模板题][分块]
		
题目链接:https://www.luogu.org/problemnew/show/P1494 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天 ...
 - [国家集训队][bzoj2038] 小Z的袜子 [莫队]
		
题面: 传送门 思路: 又是一道标准的莫队处理题目,但是这道题需要一点小改动:求个数变成了求概率 我们思考:每次某种颜色从i个增加到i+1个,符合要求的情况多了多少? 原来的总情况数是i*(i-1)/ ...
 - BZOJ2038 小Z的袜子 莫队
		
BZOJ2038 题意:q(5000)次询问,问在区间中随意取两个值,这两个值恰好相同的概率是多少?分数表示: 感觉自己复述的题意极度抽象,还是原题意有趣(逃: 思路:设在L到R这个区间中,x这个值得 ...
 
随机推荐
- LiteFlow 2.6.0版本发行注记,项目逻辑解耦的利器
			
前言 自从LiteFlow 2.5.X版本发布依赖,陆续经历了10个小版本的迭代.社区群也稳固增长,每天都有很多小伙伴在问我问题. 但是我发现最多人问我的还是:什么时候能支持界面编排? 从LiteFL ...
 - Shell-08-文本处理sed
			
文本处理sed sed:流编辑器,过滤和替换文本 工作原理:sed命令将当前处理的行读入模式空间进行处理,处理完把结果输出,并且清空模式空间. 然后再将下一行读入模式空间进行处理输出,以此类推,直到最 ...
 - Java TreeMap 和 LinkedHashMap【笔记】
			
Java TreeMap 和 LinkedHashMap[笔记] TreeMap TreeMap基本结构 TreeMap 底层的数据结构就是红黑树,和 HashMap 的红黑树结构一样 与HashMa ...
 - Block循环引用详解
			
前言 在项目中经常用到block,使用不当就很容易因为循环引用而造成内存泄漏.本文分析了block循环引用形成原因以及处理办法,如果有什么不对或者疑问请留言. 什么情况下block会造成循环引用 bl ...
 - 北航OO第四单元——UML图解析
			
北航OO第四单元--UML图解析 作业要求简析 刚接触本次作业可能需要花上一会才能搞清楚到底是要我们写个啥,在这里简单说一下: UML图的保存格式.mdj文件是以json文件的形式存储的,将每一个Um ...
 - 带你从0到1实现canvas的undo和redo功能
			
不知不觉又到了周末,又到了Fly写文章的日子,今天给大家介绍下一个web中很常见的功能, 就是撤销和复原这样一个功能,对于任何一个画图软件,或者是建模软件.没有撤销和复原.这不是傻了对啊吧,所以本篇文 ...
 - Django ORM记录的增删改查结合web端
			
模版语法分配变量 在views.py文件中定义一个视图函数show_data: def show_data(request): # 定义一个字典 并将它展示在前端HTML文件 user_dic = { ...
 - MySQL数据类型 储存引擎
			
存储引擎 日常生活中文件格式有很多种,并且针对不同的文件格式会有对应不同存储方式和处理机制(txt,pdf,word,mp4...) 针对不同的数据应该对应着不同的处理机制来存储 存储引擎就是不同的处 ...
 - noip 模拟4
			
咕 题都改不完怎么可能有空写题解啊啊啊
 - Centos7上yum安装mongodb(安装epel中的版本可能会比较老)
			
yum install epel-release 搜索mongodb-server 安装mongodb yum install mongodb-server.x86_64 配置mongodb vim ...