POJ 3416 Crossing

树状数组+离线操作

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;

int N,M;
int SUM1,SUM2,SUM3,SUM4;
int C[500000+20];

struct Point
{
    int x,y,PD,ans,id,BiX,BiY;
} point[50000*2+20];


int Lowbit(int x)
{
    return x&(-x);
}

int GetSum(int End)
{
    int sum=0;
    while(End>0)
    {
        sum=sum+C[End];
        End=End-Lowbit(End);
    }
    return sum;
}

void Update(int Start,int num)
{
    while(Start<500000+10)
    {
        C[Start]=C[Start]+num;
        Start=Start+Lowbit(Start);
    }
}

bool cmpPointX(const Point&a,const Point&b)
{
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}

bool cmpPointY(const Point&a,const Point&b)
{
    if(a.y==b.y) return a.x<b.x;
    return a.y<b.y;
}

bool cmpID(const Point&a,const Point&b)
{
    return a.id<b.id;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int i,j;
        scanf("%d%d",&N,&M);
        memset(C,0,sizeof(C));
        for(i=0; i<N; i++)
        {
            scanf("%d%d",&point[i].x,&point[i].y);
            point[i].PD=0;
            point[i].x++;
            point[i].y++;
            point[i].id=-1;
        }
        for(i=N; i<N+M; i++)
        {
            scanf("%d%d",&point[i].x,&point[i].y);
            point[i].id=i;
            point[i].PD=1;
            point[i].x++;
            point[i].y++;
        }
        int tot=0;
        sort(point,point+N+M,cmpPointX);
        for(i=0;i<N+M;i++)
            if(point[i].PD)
                point[i].BiX=i-tot,tot++;
        tot=0;
        sort(point,point+N+M,cmpPointY);
        for(i=0;i<N+M;i++)
            if(point[i].PD)
                point[i].BiY=i-tot,tot++;
        for(i=0;i<N+M;i++)
        {
            if(!point[i].PD) Update(point[i].x,1);
            else
            {
                SUM2=GetSum(point[i].x);
                SUM1=point[i].BiY-SUM2;
                SUM3=point[i].BiX-SUM2;
                SUM4=N-SUM1-SUM2-SUM3;
                point[i].ans=SUM1+SUM3-SUM2-SUM4;
            }
        }
        sort(point,point+N+M,cmpID);
        for(i=0; i<N+M; i++)
            if(point[i].PD)
                printf("%d
",max(point[i].ans,-point[i].ans));
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/4694163.html