POJ 3416 Crossing
阿新 • • 發佈:2017-08-30
題意 break oss using con stream 當前 names ems
題目: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; }
POJ 3416 Crossing