• 二维莫队(离线)


    什么是莫队算法

    莫队算法


    何谓二维莫队

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


    适用范围

    同一维莫队。


    二维莫队的思路

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


    时间复杂度分析

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

    假设询问次数为$q$,长和宽同阶,所以都设为$n$,设块长为$sqrt{n}$,那么我们会有$n$块,现在对于每一次询问,对于按块大小排序的端点,其最多会移动长为$2 imes sqrt{n}$的距离(从一个角到另一个角),而对于直接按大小的端点,对于每一个块,都有可能会移动到整张图的一个角,再移动回来,而这个次数是$q$次,再加上要将问题排序,所以时间复杂度为:$Theta(qlog q+q imes nsqrt{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
    ",ans[i]);
    	return 0;
    }
    

    例题

    $alpha.$蔬菜

  • 相关阅读:
    sqlserver sql优化案例及思路
    mysql执行计划常用说明
    MYSQL 的rownum
    innodb crash
    spring-mybatis源码追踪
    mylyn提交到JIRA的日期格式错误
    [google面试CTCI] 2-1.移除链表中重复元素
    [google面试CTCI] 2-0.链表的创建
    [google面试CTCI] 1-8.判断子字符串
    [google面试CTCI] 1-7.将矩阵中特定行、列置0
  • 原文地址:https://www.cnblogs.com/wzc521/p/11577569.html
Copyright © 2020-2023  润新知