为什么二维线段树过不了捏
查看原帖
为什么二维线段树过不了捏
256970
xie_lzh楼主2022/11/5 18:57

rt, TLE 70ptTLE\ 70pt 但二维线段树理论上是 O(nlog22n)O(n{log_2}^2n) 的,显然能过 5e5

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5,INF=10000000;
int n,m,x,y,rt,tot,a,b,c,d;
struct segment
{
    int lls,lrs,rls,rrs,sum;
}tr[N*24];
inline void update(int &p,int l,int r,int up,int dw,int x,int y)
{
    if(!p) p=++tot;
    tr[p].sum++;
    if(l==r&&up==dw) return ;
    int mid1=(l+r)>>1,mid2=(up+dw)>>1;
    if(x<=mid1&&y<=mid2) update(tr[p].lls,l,mid1,up,mid2,x,y);
    else if(x>mid1&&y<=mid2) update(tr[p].rls,mid1+1,r,up,mid2,x,y);
    else if(x<=mid1&&y>mid2) update(tr[p].lrs,l,mid1,mid2+1,dw,x,y);
    else update(tr[p].rrs,mid1+1,r,mid2+1,dw,x,y);
}
inline int query(int p,int l,int r,int up,int dw,int L,int R,int UP,int DW)
{
    if(L<=l&&r<=R&&UP<=up&&dw<=DW) return tr[p].sum;
    int mid1=(l+r)>>1,mid2=(up+dw)>>1,res=0;
    if(L<=mid1&&UP<=mid2) res+=query(tr[p].lls,l,mid1,up,mid2,L,R,UP,DW);
    if(R>mid1&&UP<=mid2) res+=query(tr[p].rls,mid1+1,r,up,mid2,L,R,UP,DW);
    if(L<=mid1&&DW>mid2) res+=query(tr[p].lrs,l,mid1,mid2+1,dw,L,R,UP,DW);
    if(R>mid1&&DW>mid2) res+=query(tr[p].rrs,mid1+1,r,mid2+1,dw,L,R,UP,DW);
    return res;
}
inline void write(int x)
{
    if(x>=10) write(x/10);
    putchar(x%10+48);
}
int main()
{
    // freopen(".in","r",stdin);
    // freopen(".out","w",stdout);
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>x>>y;
        update(rt,0,INF,0,INF,x,y);
    }
    while(m--)
    {
        cin>>a>>b>>c>>d;
        write(query(rt,0,INF,0,INF,a,c,b,d));
        putchar('\n');
    }
    return 0;
}
2022/11/5 18:57
加载中...