什麼是莫隊算法html
莫隊算法算法
何謂二維莫隊spa
區別與一維莫隊,無非就是放在了二維上而已。htm
適用範圍blog
同一維莫隊。排序
二維莫隊的思路
get
依然是將問題離線,將整張圖(設長爲$n$寬爲$m$),咱們分別將長和寬分紅根號塊,而後將其編號,對於每一組詢問,咱們將其一個端點按塊的大小排序,另外一個端點直接按大小排序,能夠類比一維莫隊。io
時間複雜度分析class
時間複雜度分析是我本身$YY$的,有可能有錯,不要聲張,不要消費,私信我就行了。im
假設詢問次數爲$q$,長和寬同階,因此都設爲$n$,設塊長爲$\sqrt{n}$,那麼咱們會有$n$塊,如今對於每一次詢問,對於按塊大小排序的端點,其最多會移動長爲$2\times \sqrt{n}$的距離(從一個角到另外一個角),而對於直接按大小的端點,對於每個塊,都有可能會移動到整張圖的一個角,再移動回來,而這個次數是$q$次,再加上要將問題排序,因此時間複雜度爲:$\Theta(q\log q+q\times n\sqrt{n})$。
代碼時刻
struct rec{int 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; }
例題