emmmm,上周的比赛遇到莫队了,然而只会线段树。
特地学习一下。
参考博文: 洛谷日报
普通莫队(参考洛谷日报)
莫队算法一般分为两类,一是莫队维护区间答案,二是维护区间内的数据结构。
一般用于处理只有询问不用修改的区间问题(不过后面也有带修莫队啦)
对于区间问题来说,我们会想到线段树,但是线段树的复杂度过高,并且对于一些问题来说
例如:给出m个询问[L,R],求区间内出现次数大于等于3的个数?用线段树的话我们还是要暴力合并左右儿子:这样就不能直接o(1)从左右儿子转移到父亲,甚至是o(左儿子长度+右儿子长度),然后就凉了呗…
先看一个比较简单的问题: 给一个序列,m次询问,每次询问你区间 [ l , r ] [l,r] [l,r]有多少种不同的颜色。 n , m ≤ 100000 n,m \leq 100000 n,m≤100000
- 最简单的暴力。
最极致的超时?
对于每一次询问 q u e r y [ l , r ] query[l,r] query[l,r] 我们都进行遍历一次来找不同的颜色
显然复杂度是 O ( n m ) O(nm) O(nm) 的,很明显这会TLE
2.优美的暴力你爱吗?
换一种方式进行暴力,也是莫队算法的基础
我们定义 q l ql ql和 q r qr qr,代表当前区 间 N o w Q u e r y [ q l , q r ] 间NowQuery[ql,qr] 间NowQuery[ql,qr]内有多少种颜色
再定义一个cnt数组, c n t i cnt_{i} cnti表示第i种颜色在 Q u e r y [ q l , q r ] Query[ql,qr] Query[ql,qr]内出现了多少次。
对于每一个询问 Q u e r y [ l , r ] Query[l,r] Query[l,r],我们会挪动 l l l 到 q l ql ql, r r