二维莫队(离线)

Posted wzc521

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二维莫队(离线)相关的知识,希望对你有一定的参考价值。

什么是莫队算法

莫队算法


何谓二维莫队

区别与一维莫队,无非就是放在了二维上而已。


适用范围

同一维莫队。


二维莫队的思路

依然是将问题离线,将整张图(设长为$n$宽为$m$),我们分别将长和宽分成根号块,然后将其编号,对于每一组询问,我们将其一个端点按块的大小排序,另一个端点直接按大小排序,可以类比一维莫队。


时间复杂度分析

时间复杂度分析是我自己$YY$的,有可能有错,不要声张,不要消费,私信我就好了。

假设询问次数为$q$,长和宽同阶,所以都设为$n$,设块长为$\\sqrtn$,那么我们会有$n$块,现在对于每一次询问,对于按块大小排序的端点,其最多会移动长为$2\\times \\sqrtn$的距离(从一个角到另一个角),而对于直接按大小的端点,对于每一个块,都有可能会移动到整张图的一个角,再移动回来,而这个次数是$q$次,再加上要将问题排序,所以时间复杂度为:$\\Theta(q\\log q+q\\times n\\sqrtn)$。


代码时刻

struct recint x0,y0,x2,y2,pos,id;e[100001];
int r,c,q;
int sqrr,sqrc;
int ans[100001];
int uu,dd,ll,rr;
bool cmp(rec a,rec b)return a.x0/sqrr==b.x0/sqrr?(a.y0/sqrc==b.y0/sqrc?(a.x2/sqrr==b.x2/sqrr?a.y2/sqrc<b.y2/sqrc:a.x2<b.x2):a.y0<b.y0):a.x0<b.x0;
int main()

	scanf("%d%d%d",&r,&c,&q);
	sqrr=sqrt(r);sqrc=sqrt(c);
	for(int i=1;i<=q;i++)
	
		scanf("%d%d%d%d",&e[i].x0,&e[i].y0,&e[i].x2,&e[i].y2);
		e[i].id=i;
	
	sort(e+1,e+q+1,cmp);
	ll=rr=e[1].x0;
	uu=dd=e[1].y0;
	for(int i=1;i<=q;i++)
	
		while(uu>e[i].y0)upd(--uu,ll,rr,0,1);
		while(uu<e[i].y0)upd(uu++,ll,rr,0,0);
		while(dd<e[i].y2)upd(++dd,ll,rr,0,1);
		while(dd>e[i].y2)upd(dd--,ll,rr,0,0);
		while(ll>e[i].x0)upd(--ll,uu,dd,1,1);
		while(ll<e[i].x0)upd(ll++,uu,dd,1,0);
		while(rr<e[i].x2)upd(++rr,uu,dd,1,1);
		while(rr>e[i].x2)upd(rr--,uu,dd,1,0);
		ans[e[i].id]=ans[0];
	
	for(int i=1;i<=q;i++)printf("%d\\n",ans[i]);
	return 0;


例题

$\\alpha.$蔬菜

以上是关于二维莫队(离线)的主要内容,如果未能解决你的问题,请参考以下文章

反省——关于csp-s模拟50

csp-s模拟测试50(9.22)「施工(单调栈优化DP)」·「蔬菜(二维莫队???)」·「联盟(树上直径)」

HDU多校1 - 6959 zoto(莫队+树状数组/值域分块)

CSU 1786 莫队+KDTree

静态二维数点问题离线解法的一种设想

洛谷 - P2163 [SHOI2007]园丁的烦恼(离线二维数点)