2017-2018 ACM-ICPC Northern Eurasia (Northeastern European Regional) Contest (NEERC 17) A

传送门
训练时候没有考虑到这样一个性质,得到栗子大佬的点拨才看出来:打到的圆一定是左边或右边第一个直径高出射击高度的圆。
2017-2018 ACM-ICPC Northern Eurasia (Northeastern European Regional) Contest (NEERC 17) A_第1张图片
如上图,如果点A不落在圆C内却落在圆D内,显然线段AB在圆D内且线段AB与圆C相交,则圆D与圆C相交,不符合题意描述。
再用线段树维护一下即可。

#include 
using namespace std;
const int maxn=200003;
int n;
struct query{
    int typ, x, y, id;
}que[maxn];
int x[maxn];
int my[maxn<<2];
int id[maxn<<2];
void pushup(int u){
    my[u]=max(my[2*u], my[2*u+1]);
}
void build(int u, int l, int r){
    my[u]=0;
    if(l==r){
        return;
    }
    int mid=(l+r)/2;
    build(2*u, l, mid);
    build(2*u+1, mid+1, r);
}
void update(int u, int pos, int l, int r, int i){
    if(pos>r||posreturn;
    if(l==r){
        id[u]=i;
        my[u]=que[i].y;
        return ;
    }
    int mid=(l+r)/2;
    update(2*u, pos, l, mid, i);
    update(2*u+1, pos, mid+1, r, i);
    pushup(u);
}
int Ql(int u, int ql, int qr, int l, int r, int i){
    if(qrr||my[u]*2<=que[i].y)return 0;
    if(l==r){
        if(1ll*(que[id[u]].x-que[i].x)*(que[id[u]].x-que[i].x)+1ll*(que[id[u]].y-que[i].y)*(que[id[u]].y-que[i].y)<1ll*que[id[u]].y*que[id[u]].y){
            printf("%d\n", id[u]);
            id[u]=0;
            my[u]=0;
            return 1;
        }
        return -1;
    }
    int mid=(l+r)/2;
    int ret1=Ql(2*u+1, ql, qr, mid+1, r, i);
    int ret=0;
    if(ret1==1)ret=1;
    else if(ret1==-1)ret=-1;
    else ret=Ql(2*u, ql, qr, l, mid, i);
    pushup(u);
    return ret;
}
int Qr(int u, int ql, int qr, int l, int r, int i){
    if(qrr||my[u]*2<=que[i].y)return 0;
    if(l==r){
        if(1ll*(que[id[u]].x-que[i].x)*(que[id[u]].x-que[i].x)+1ll*(que[id[u]].y-que[i].y)*(que[id[u]].y-que[i].y)<1ll*que[id[u]].y*que[id[u]].y){
            printf("%d\n", id[u]);
            id[u]=0;
            my[u]=0;
            return 1;
        }
        return -1;
    }
    int mid=(l+r)/2;
    int ret1=Qr(2*u, ql, qr, l, mid, i);
    int ret=0;
    if(ret1==1)ret=1;
    else if(ret1==-1)ret=-1;
    else ret=Qr(2*u+1, ql, qr, mid+1, r, i);
    pushup(u);
    return ret;
}
int main(){
    scanf("%d", &n);
    for(int i=1;i<=n;i++){
        scanf("%d%d%d", &que[i].typ, &que[i].x, &que[i].y);
        que[i].id=i;
        x[i]=que[i].x;
    }
    sort(x+1, x+1+n);
    build(1, 1, n);
    for(int i=1;i<=n;i++){
        if(que[i].typ==1){
            int pos=lower_bound(x+1, x+1+n, que[i].x)-x;
            update(1, pos, 1, n, i);
        }
        else {
            int pos=lower_bound(x+1, x+1+n, que[i].x)-x;
            if(Ql(1, 1, pos, 1, n, i)!=1&&Qr(1, pos, n, 1, n, i)!=1){
                printf("-1\n");
            }
        }
    }
}

你可能感兴趣的:(数据结构)