*UVALive 6656 - Watching the Kangaroo(二分)

来源:互联网 发布:易道打车软件 编辑:程序博客网 时间:2024/06/01 08:06

题目:

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=84227#problem/G

题意:

n个区间,m个询问。给出左右区间的坐标,询问x,若在区间内则求出与两端点的最小值,对于所有区间取最大值。

思路:

将所有的区间以中点为界,分成两个区间。对于两个区间进行二分查找最大值。

AC.

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 1e5+5;struct node {    int l, r;};node lef[maxn], rig[maxn];int id1[maxn], id2[maxn];bool cmp1(node x, node y){    if(x.l == y.l) return x.r > y.r;    return x.l < y.l;}bool cmp2(node x, node y){    if(x.r == y.r) return x.l > y.l;    return x.r < y.r;}int main(){    //freopen("in", "r", stdin);    int T, ca = 1;    scanf("%d", &T);    while(T--) {        int n, m;        scanf("%d %d", &n, &m);        for(int i = 0; i < n; ++i) {            int a, b, mid;            scanf("%d %d", &a, &b);            mid = (a+b)/2;            lef[i].l = a; lef[i].r = mid;            rig[i].l = mid; rig[i].r = b;            if((a+b)%2) rig[i].l++; //如果区间长度为偶数        }        sort(lef, lef+n, cmp1);        sort(rig, rig+n, cmp2);        int cnt1 = 0, cnt2 = 0;        int tmp = -1;        for(int i = 0; i < n; ++i) {            if(lef[i].r > tmp) {                id1[cnt1++] = i;                tmp = lef[i].r;            }        }        tmp = 1000000005;        for(int i = n-1; i >= 0; --i) {            if(rig[i].l < tmp) {                id2[cnt2++] = i;                tmp = rig[i].l;            }        }        printf("Case %d:\n", ca++);        while(m--) {            int x;            scanf("%d", &x);            if(x >= rig[id2[0]].r || x <= lef[id1[0]].l) {                printf("0\n");                continue;            }            int ans = 0;            int l = 0, r = cnt1-1, mid, it;            while(l <= r) {                mid = (l+r) / 2;                it = id1[mid];                if(lef[it].r >= x) {                    ans = max(ans, x - lef[it].l);                    r = mid-1;                }                else l = mid+1;            }            l = 0; r = cnt2-1;            while(l <= r) {                mid = (l+r)/2;                it = id2[mid];                if(rig[it].l <= x) {                    ans = max(ans, rig[it].r - x);                    r = mid-1;                }                else l = mid + 1;            }            printf("%d\n", ans);        }    }    return 0;}



0 0