题目大意:给定平面上的一些点,多次询问某个矩形中有多少个点
将每个询问拆成4个 然后把所有询问和点都按照横坐标排序
对于每个询问,将所有x值小于等于这个询问的x的点的y值加入树状数组 然后在树状数组上查询小于等于这个询问的y值的点的数量
别被1000W吓到了 如果不爆内存的话1E也是能搞的 套个log就没多少了
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 500500 using namespace std; struct point{ int x,y; void Read() { scanf("%d%d",&x,&y); ++x;++y; } bool operator < (const point &Y) const { return x < Y.x ; } }points[M]; struct query{ int x,y,pos,flag; query(){} query(int _,int __,int ___,int ____): x(_),y(__),pos(___),flag(____){} bool operator < (const query &Y) const { return x < Y.x ; } }queries[M<<2]; int n,m,ans[M]; int c[10001000]; void Update(int x) { for(;x<=10000000;x+=x&-x) c[x]++; } int Get_Ans(int x) { int re=0; for(;x;x-=x&-x) re+=c[x]; return re; } int main() { int i,j,x1,y1,x2,y2; cin>>n>>m; for(i=1;i<=n;i++) points[i].Read(); sort(points+1,points+n+1); for(i=1;i<=m;i++) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); ++x2;++y2; queries[i*4-3]=query(x1,y1,i,1); queries[i*4-2]=query(x1,y2,i,-1); queries[i*4-1]=query(x2,y1,i,-1); queries[i<<2 ]=query(x2,y2,i,1); } sort(queries+1,queries+m*4+1); for(i=1,j=1;i<=m<<2;i++) { for(;j<=n && points[j].x<=queries[i].x;j++) Update(points[j].y); ans[queries[i].pos]+=Get_Ans(queries[i].y)*queries[i].flag; } for(i=1;i<=m;i++) printf("%d\n",ans[i]); }