BJ simulates Rectangle Query [block + bitset]

Topic description:

on the plane n points you need to answer q query:
given x 1 , x 2 , and 1 , and 2 , in satisfying x 1 x x 2 and and 1 and and 2 all points of ( x , and ) , how many different abscissas (x-coordinates) and different ordinates (y-coordinates) are there?
forced online, n , q 50000

Problem solving ideas:

Block + bitset.
Discretize the coordinates. Sort the points by x-coordinate from small to large and divide the points into n Blocks, use bitset to store the points of each block, pay attention to divide the blocks according to the number of points, not according to the coordinates.

If the abscissa of any two points is different and the ordinate of any two points is different, then we can query the abscissa in [ x 1 , x 2 ] collection of points. Do the y coordinate again according to the above process, you can get the ordinate in [ and 1 , and 2 ] collection of points. The intersection of the two is the desired point set.

In order to remove the duplication, we use some tricks. For each point, we change the ordinate value of the point to the point with the same abscissa, the ordinate smaller than it, and the closest point to it. Then, we ask again for the ordinate in [ 1 , and 1 ) The intersection of the set of points and the set of answers just obtained is the point with the smallest ordinate under each abscissa, so that the number of different abscissas is obtained. The ordinate is the same.

The time complexity is O ( n n + n q 64 )

#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define mp make_pair
#define X first
#define Y second
using namespace std;
int getint()
{
    int i=0,f=1;char c;
    for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar());
    if(c=='-')c=getchar(),f=-1;
    for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
    return i*f;
}
const int N=50005,B=250,INF=0x3f3f3f3f;
int online,n,m,S,tot,x[N],y[N];
pii p[N];vector<pii >vec[N];
struct BIT
{
    pii p[N];
    bitset<N>bit[B];
    void Init()
    {
        sort(p+1,p+n+1);
        for(int i=1;i<=n;i++)
            for(int j=(i+S-1)/S;j<=tot;j++)
                bit[j][p[i].Y]=1;
    }
    bitset<N>Get(int x)
    {
        bitset<N>ret;
        int loc=lower_bound(p+1,p+n+1,mp(x,INF))-p-1;
        if(!loc)return ret;
        int b=(loc+S-1)/S;ret=bit[b-1];
        for(int i=(b-1)*S+1;i<=loc;i++)ret[p[i].Y]=1;
        return ret;
    }
    bitset<N>Query(int l,int r){return Get(r)^Get(l-1);}
}g[4];
void decode(int &x1,int &y1,int &x2,int &y2,int ansx,int ansy)
{
    x1+=online*(ansx+ansy); y1+=online*(ansx+ansy); x2+=online*(ansx+ansy); y2+=online*(ansx+ansy);
    x1=lower_bound(x+1,x+n+1,x1)-x;
    y1=lower_bound(y+1,y+n+1,y1)-y;
    x2=upper_bound(x+1,x+n+1,x2)-x-1;
    y2=upper_bound(y+1,y+n+1,y2)-y-1;
}
int main()
{
    //freopen("lx.in","r",stdin);
    online=getint(),n=getint();
    for(int i=1;i<=n;i++)p[i].X=getint(),p[i].Y=getint();
    for(int i=1;i<=n;i++)x[i]=p[i].X,y[i]=p[i].Y;
    sort(x+1,x+n+1),sort(y+1,y+n+1);
    for(int i=1;i<=n;i++)
    {
        p[i].X=lower_bound(x+1,x+n+1,p[i].X)-x;
        p[i].Y=lower_bound(y+1,y+n+1,p[i].Y)-y;
    }
    S=sqrt(n),tot=(n+S-1)/S;
    for(int i=1;i<=n;i++)g[0].p[i]=mp(p[i].X,i),g[1].p[i]=mp(p[i].Y,i);
    g[0].Init(),g[1].Init();
    int cnt=0;
    for(int i=1;i<=n;i++)vec[p[i].X].push_back(mp(p[i].Y,i));
    for(int i=1;i<=n;i++)if(vec[i].size())
    {
        sort(vec[i].begin(),vec[i].end());
        for(int j=0;j<vec[i].size();j++)
            g[2].p[++cnt]=mp(j?vec[i][j-1].X:0,vec[i][j].Y);
        vec[i].clear();
    }
    g[2].Init();
    cnt=0;
    for(int i=1;i<=n;i++)vec[p[i].Y].push_back(mp(p[i].X,i));
    for(int i=1;i<=n;i++)if(vec[i].size())
    {
        sort(vec[i].begin(),vec[i].end());
        for(int j=0;j<vec[i].size();j++)
            g[3].p[++cnt]=make_pair(j?vec[i][j-1].X:0,vec[i][j].Y);
        vec[i].clear();
    }
    g[3].Init();
    int ansx=0,ansy=0;m=getint();
    while(m--)
    {
        int x1=getint(),y1=getint(),x2=getint(),y2=getint();
        decode(x1,y1,x2,y2,ansx,ansy);
        bitset<N>t=g[0].Query(x1,x2)&g[1].Query(y1,y2);
        ansx=(t&g[2].Get(y1-1)).count();
        ansy=(t&g[3].Get(x1-1)).count();
        printf("%d %d\n",ansx,ansy);
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326143385&siteId=291194637