2012 ACM/ICPC Asia Regional Changchun Online Alice and Bob
http://acm.hdu.edu.cn/showproblem.php?pid=4268
思路:贪心+树状数组。
把两个人的x,y按x优先排序,然后离散化。
然后从alice的最小x开始枚举,把bob的所有的Xb<=Xa的Yb都放到一个堆里。
然后在堆里找一个最大的Yb,使得Yb<=Ya,找到则删除。(可以转化树状数组找第k大哈)

#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #define lowbit(x) (x)&(-x) using namespace std; const int maxn = 100005; struct nd { int x,y; }a[maxn],b[maxn]; int sum[maxn*4]; bool cmp(nd a,nd b) { if(a.x^b.x)return a.x < b.x; return a.y < b.y; } int K; int bitser(int x,int n) { int l = 1,r = n,md; while(l<r){ md = (l + r) >> 1; if(sum[md]>=x)r = md; else l = md + 1; }return l; } void add(int x,int v){for(;x<=K;x+=lowbit(x))sum[x]+=v;} int getsum(int x){int v=0;for(;x;x-=lowbit(x))v+=sum[x];return v;} int findk(int k) { int pos = 0,cnt = 0; for(int i = 19; i >= 0; -- i){ pos += (1<<i); if(pos>=K || cnt+sum[pos]>=k) pos -= (1<<i); else cnt += sum[pos]; }return pos + 1; } int main() { int i,j,k,t,n; scanf("%d",&t); while(t--){ scanf("%d",&n); k = 0; for(i = 1; i <= n; ++ i){ scanf("%d %d",&a[i].x,&a[i].y); sum[++k] = a[i].x; sum[++k] = a[i].y; } for(i = 1; i <= n; ++ i){ scanf("%d %d",&b[i].x,&b[i].y); sum[++k] = b[i].x; sum[++k] = b[i].y; } K = k; sort(sum+1,sum+k+1); sort(a+1,a+n+1,cmp); sort(b+1,b+n+1,cmp); for(i = 1; i <= n; ++ i) { a[i].x = bitser(a[i].x,k); a[i].y = bitser(a[i].y,k); b[i].x = bitser(b[i].x,k); b[i].y = bitser(b[i].y,k); } memset(sum,0,sizeof(sum)); int ans = 0; k = 1; for(i = 1; i <= n; ++ i){ while(k<=n && a[i].x>=b[k].x){ add(b[k].y,1); k++; } j = getsum(a[i].y); if(j){ j = findk(j); ans++; add(j,-1); } } printf("%d\n",ans); } return 0; }