您的位置:首页 > 其它

莫队算法学习小记

2016-04-28 20:49 281 查看
先前还以为莫队算法是一个高级的东西。

可是仔细学习了一下,才发现这东西应该叫做——

一个优雅的暴力

对于一个询问区间[l,r],如果我们可以O(1)的得到区间[l,r-1],[l,r+1],[l-1,r],[l+1,r]的答案,那么从这个询问转移到另一个询问的时间复杂度为O(|l-l’|+|r-r’|)。

那我们可以确定一个解决询问的顺序,从而使复杂度达到O(n^1.5)

我们把每个询问看做二位平面上的一个点,那么如果我们对这个东西做最小生成树,那么沿着树边做一定是最优解。

不管你会不会,反正我不会。

但是,如果莫队算法这么复杂的话,它也不会这么普及。

这个算法有一个优雅的替代品——分块(分块大法好)。

我们把所有的询问排序,第一关键字为左端点所在块的编号,第二关键字为右端点的编号。

为什么这样做也是O(n^1.5)的呢?

考虑i和i+1,若它们在同一块里,那么r最多增加n。单调递增,这样的东西最多有n^0.5个,所以复杂度为O(n^1.5)。

若它们在不同的块,那么r的变化也是n。这样的东西也有n^0.5个,所以也是O(n^1.5)

那么总的复杂度就是O(n^1.5)

Code

pl=1;
fo(i,1,m) {
if (pr<ask[i].r) fo(j,pr+1,ask[i].r) updata(j,1);
else fo(j,ask[i].r+1,pr) updata(j,-1);
if (pl<ask[i].l) fo(j,pl,ask[i].l-1) updata(j,-1);
else fo(j,ask[i].l,pl-1) updata(j,1);
pr=ask[i].r;pl=ask[i].l;
}


updata视情况而定。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: