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大哈)

View Code
#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;
}

posted on 2012-09-08 18:15  aigoruan  阅读(285)  评论(0)    收藏  举报

导航