背景:由于莫涛经常打比赛做队长,大家都叫他莫队,该算法也被称为莫队算法。
时间复杂度:O((n+m)×n^0.5),稍后说明。
原理:基于暴力的一种算法。用于与区间查询有关的操作;
将n个数分为n^0.5块,给这些块排序(一种特殊的排序方法,按所在块排序),然后就可以进行我们我们希望的操作了。
算一下时间复杂度:
考虑一下在同一个块的时候。由于L的范围是确定的,所以每次L的偏移量是O(√N)
但是r的范围没有确定;r的偏移量是O(N)。
那么从一个块到另一个块呢?
明显地,r我们不需要作考虑,仍然是O(N)。
而L明显最多也是2*√N,而且这种情况下,很快就会到下下一块。所以也是O(√N)
由于有√N(根号N)个块,所以r的总偏移量是O(N*√N)
而M个询问,每个询问都可以让L偏移O(√N),所以L的总偏移量O(M*√N)
注意了,时间复杂度分析的时候一定要注意,r的偏移量和询问数目是没有直接关系的。
而L则恰恰相反;L的偏移量我们刚才也说明了,它和块的个数没有直接关系。
所以总的时间复杂度是:
O((N+M)*√N)
核心(以下这段代码和设计add和del函数):
int l=1,r=0;//初始化
for(int i=1;i<=m;i++)//m次询问操作
{
//是先加还是后加,看图理解
while(r<q[i].r)add(++r);
while(l>q[i].l)add(--l);
while(r>q[i].r)del(r--);
while(l<q[i].l)del(l++);
}
具体还要多做题