题目大意:给出平面中的一些点,询问平面中的一些矩形中有多少点。
思路:正常应该是二维树状数组,然后数据范围太大。所以就只能按照一个坐标排序,另一个坐标跑树状数组。注意离线操作,一个问题拆成4个。
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 500010 #define RANGE 10000010 using namespace std; struct Point{ int x,y; bool operator <(const Point &a)const { return x < a.x; } void Read() { scanf("%d%d",&x,&y); ++x,++y; } }point[MAX]; struct Ask{ int x,y; int from,ratio; Ask(int _,int __,int ___,int ____):x(_),y(__),from(___),ratio(____) {} Ask() {} bool operator <(const Ask &a)const { return x < a.x; } }ask[MAX << 2]; int points,asks,cnt; int fenwick[RANGE]; int ans[MAX]; inline void Fix(int x) { for(; x < RANGE; x += x&-x) ++fenwick[x]; } inline int GetSum(int x) { int re = 0; for(; x; x -= x&-x) re += fenwick[x]; return re; } int main() { cin >> points >> asks; for(int i = 1; i <= points; ++i) point[i].Read(); for(int x1,y1,x2,y2,i = 1; i <= asks; ++i) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); ++x1,++x2,++y1,++y2; ask[++cnt] = Ask(x1 - 1,y1 - 1,i,1); ask[++cnt] = Ask(x1 - 1,y2,i,-1); ask[++cnt] = Ask(x2,y1 - 1,i,-1); ask[++cnt] = Ask(x2,y2,i,1); } sort(point + 1,point + points + 1); sort(ask + 1,ask + cnt + 1); int now = 1; for(int i = 1; i <= cnt; ++i) { for(; point[now].x <= ask[i].x && now <= points; ++now) Fix(point[now].y); ans[ask[i].from] += GetSum(ask[i].y) * ask[i].ratio; } for(int i = 1; i <= asks; ++i) printf("%d\n",ans[i]); return 0; }
时间: 2024-10-20 10:38:18