先膜一下莫队%%%%%%%%%%%%%%%%%%%
序列上的莫队
对于n个数的序列,当我们知道区间上[L,R]的答案时,可以很快求出[L,R-1],[L,R+1,],[L+1,R],[L-1,R]时,我们可以可以考虑使用莫队(网上千篇一律都是这么说的)
例题:
有n个数字,以及m个查询。
每次查询的格式是L,R,求L~R这个区间内不同数字的个数。
很显然线段数无法给出一个优良的时间复杂度
那我们使用莫队,怎么使用莫队呢,我们先将n个数分块,分成sqrt(n)块。
对于所有m个询问按照 L 所在块升序,L相同时按照R升序排序。
每次查询移动时 增加一个数i就使num[i]++,num[i]==1代表这个数之前没出现过,就使ans++(ans代表区间内不同数字的个数),减少一个数i就使num[i]--,num[i]==0代表这个数之前出现过,ans--;
时间复杂度分析:
那么当询问L所在块不变时,L每次最多移动sqrt(n)次,共有m次查询时间复杂度为m*sqrt(n)
当询问L所在块不变时,R由于升序排列,在同一块内移动的时间复杂度为O(N),共有sqrt(n)块,时间复杂度为sqrt(n)*n;
从一个块到另一个块时,L每次最多移动2*sqrt(n)次,共有sqrt(n)块,时间复杂度为2*n*sqrt(n)
从一个块到另一个块时,R每次最多移动N,共有sqrt(n)块,时间复杂度为n*sqrt(n)
所以总时间复杂度大概差不多几乎就是 O( n*sqrt(n) )了。。。。。。。。。。。。。。。。。