树状数组+离线操作
#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; }