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

这样的圆应该不会太多。

1.学会了二分取左右边界的方法,记得要取min和max防止越界。
2.学会了一种新的线段树的写法,父节点并不完全包含子节点,相反地,父节点拥有的元素,子节点不会再拥有。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MAXN = 2e5 + 1e2;

struct Oper {
    int t, x, y, px, lx, rx;
    Oper() {}
    Oper(int t, int x, int y): t(t), x(x), y(y) {}
} oper[MAXN + 5];

#define lt ls,l,m
#define rt rs,m+1,r
#define ls (o<<1)
#define rs (o<<1|1)

set<int> st[MAXN * 4 + 5];

void Update(int o, int l, int r, int ql, int qr, int id, int d) {
    if((ql <= l && r <= qr)) {
        if(d == 1)
            st[o].insert(id);
        else
            st[o].erase(id);
        return;
    } else {
        int m = l + r >> 1;
        if(ql <= m)
            Update(lt, ql, qr, id, d);
        if(qr >= m + 1)
            Update(rt, ql, qr, id, d);
    }
}

int QueryHelp(int o, int id) {
    int px = oper[id].x, py = oper[id].y;
    for(auto si : st[o]) {
        int x = oper[si].x, y = oper[si].y;
        if(1ll * (x - px) * (x - px) + 1ll * (y - py) * (y - py) < 1ll * y * y)
            return si;
    }
    return -1;
}

int Query(int o, int l, int r, int id, int x) {
    int res = QueryHelp(o, id);
    if(l == r || res != -1)
        return res;
    int m = l + r >> 1;
    if(x <= m)
        return Query(lt, id, x);
    else
        return Query(rt, id, x);
}

int px[MAXN + 5], xtop;

int main() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
#endif // Yinku
    int n;
    scanf("%d", &n);
    xtop = 0;
    for(int i = 1; i <= n; ++i) {
        int t, x, y;
        scanf("%d%d%d", &t, &x, &y);
        px[++xtop] = x;
        oper[i] = Oper(t, x, y);
    }
    sort(px + 1, px + 1 + xtop);
    xtop = unique(px + 1, px + 1 + xtop) - (px + 1);
    for(int i = 1; i <= n; ++i)
        oper[i].px = lower_bound(px + 1, px + 1 + xtop, oper[i].x) - px;

    for(int i = 1; i <= n; ++i) {
        if(oper[i].t == 1) {
            int lx = (oper[i].x - oper[i].y), rx = (oper[i].x + oper[i].y);
            lx = min(xtop, upper_bound(px + 1, px + 1 + xtop, lx) - px);
            rx = max(1, (lower_bound(px + 1, px + 1 + xtop, rx) - px) - 1);
            oper[i].lx = lx, oper[i].rx = rx;
            Update(1, 1, xtop, lx, rx, i, 1);
        } else {
            int res = Query(1, 1, xtop, i, oper[i].px);
            printf("%d\n", res);
            if(res != -1)
                Update(1, 1, xtop, oper[res].lx, oper[res].rx, res, -1);
        }
    }
}
上一篇:[NOI Online #2 提高组]子序列问题


下一篇:洛谷 P3865 【模板】ST表(区间查询)