标签:tor ble ring log ios while ros scanf cstring
题目:http://poj.org/problem?id=3416
题意:给你一些点,之后再给你一些点来建立坐标系,问你一三象限的点个数和二四象限的点个数的差
这个题目我们应该离线处理,考虑建立2个树状数组,一个维护当前坐标系的右边点数目,一个维护左边
首先对点和查询的点进行以x从小到大排序,开始将所有点放入右边
之后开始枚举要查询的点,将在该点左边的数从右边删除并加入左边,然后分别求和算结果
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> #include<set> using namespace std; const int N=5e5+5; struct p { int x,y,id; bool operator <(const p&t) const { return x<t.x; } }; p a[N],b[N]; int n,m; int l[N],r[N],ans[N]; void add(int *s,int i,int x) { while(i<=500001) { s[i]+=x; i+=i&-i; } } int sum(int *s,int i) { int tem=0; while(i>0) { tem+=s[i]; i-=i&-i; } return tem; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y); for(int i=1;i<=m;i++) { scanf("%d%d",&b[i].x,&b[i].y); b[i].id=i; } sort(a+1,a+1+n); sort(b+1,b+1+m); memset(l,0,sizeof(l)); memset(r,0,sizeof(r)); for(int i=1;i<=n;i++) add(r,a[i].y+1,1); int st=1,ed; for(int i=1;i<=m;i++) { for(ed=st;ed<=n;ed++) if (a[ed].x>b[i].x) break; for(int j=st;j<ed;j++) { add(r,a[j].y+1,-1); add(l,a[j].y+1,1); } int t=sum(r,500001)-sum(r,b[i].y+1)+sum(l,b[i].y+1); int tt=sum(l,500001)-sum(l,b[i].y+1)+sum(r,b[i].y+1); ans[b[i].id]=abs(t-tt); st=ed; } for(int i=1;i<=m;i++) printf("%d\n",ans[i]); if (T) printf("\n"); } return 0; }
标签:tor ble ring log ios while ros scanf cstring
原文地址:http://www.cnblogs.com/bk-201/p/7452085.html