四分树的满平面维护的卡常
  • 板块学术版
  • 楼主reveal
  • 当前回复4
  • 已保存回复4
  • 发布时间2022/3/16 13:09
  • 上次更新2023/10/28 06:28:35
查看原帖
四分树的满平面维护的卡常
523491
reveal楼主2022/3/16 13:09

维护一个满平面(每个整点都需要维护信息)的情况下,经测试似乎 KDT 比四分树略快(5%?)。

正题:

维护一个满平面(每个整点都需要维护信息)。

此人看到用时为他 1/10 的标程之后,盯着四分树陷入了沉思,并十分好奇这种东西怎么卡常。

struct ST{
    ll mx[N<<5],add[N<<5];
    int s[N<<5][4],size;
    void _add(int x,ll z){
        mx[x]+=z;
        add[x]+=z;
    }
    void pushdown(int x){
        if(add[x]){
            _add(s[x][0],add[x]);
            if(s[x][1]) _add(s[x][1],add[x]);
            if(s[x][2]){
                _add(s[x][2],add[x]);
                if(s[x][3]) _add(s[x][3],add[x]);
            }
            add[x]=0;
        }
    }
    void build(int p=1,int l0=0,int r0=lex,int l1=0,int r1=ley){
        s[p][0]=s[p][1]=s[p][2]=s[p][3]=add[p]=0;
        if(l0==r0&&l1==r1){
            mx[p]=b[l0][l1];
            return;
        }
        int mdx=(l0+r0)>>1,mdy=(l1+r1)>>1;
        build(s[p][0]=++size,l0,mdx,l1,mdy);
        if(l1!=r1) build(s[p][1]=++size,l0,mdx,mdy+1,r1);
        if(l0!=r0){
            build(s[p][2]=++size,mdx+1,r0,l1,mdy);
            if(l1!=r1) build(s[p][3]=++size,mdx+1,r0,mdy+1,r1);
        }
        mx[p]=max(max(mx[s[p][0]],mx[s[p][1]]),max(mx[s[p][2]],mx[s[p][3]]));
    }
    ll get(int x0,int y0,int x1,int y1,int c,int p=1,int l0=0,int r0=lex,int l1=0,int r1=ley){
        if(x0<=l0&&r0<=y0&&x1<=l1&&r1<=y1){
            _add(p,c);
            return(mx[p]-c);
        }
        pushdown(p);
        int mdx=(l0+r0)>>1,mdy=(l1+r1)>>1;
        ll re=0;
        if(x0<=mdx&&x1<=mdy) re=get(x0,y0,x1,y1,c,s[p][0],l0,mdx,l1,mdy);
        if(x0<=mdx&&y1>mdy&&s[p][1]) cmax(re,get(x0,y0,x1,y1,c,s[p][1],l0,mdx,mdy+1,r1));
        if(y0>mdx&&x1<=mdy&&s[p][2]) cmax(re,get(x0,y0,x1,y1,c,s[p][2],mdx+1,r0,l1,mdy));
        if(y0>mdx&&y1>mdy&&s[p][3]) cmax(re,get(x0,y0,x1,y1,c,s[p][3],mdx+1,r0,mdy+1,r1));
        mx[p]=max(max(mx[s[p][0]],mx[s[p][1]]),max(mx[s[p][2]],mx[s[p][3]]));
        return(re);
    }
}t;
2022/3/16 13:09
加载中...