Color it hdu - 6183

\(idea\)

对每个颜色开一个线段树维护最小的\(x_i\),既找该颜色离\(y\)轴最近的点\(p(x_i, y_i)\)。因为询问的范围总是\((1, x)\),那么如果\(p\)在询问范围内,则该颜色就会贡献1,也即\(x_i < x\),ans++

\(code\)

const int N = 1000105;

int tot, op;
int ls[4 * N], rs[4 * N], Min[4 * N], root[100];

void Insert(int l, int r, int& rt, int pos, int x) {
    if (!rt) {
        rt = ++tot;
        Min[rt] = x;
    }
    if (Min[rt] > x) Min[rt] = x;

    if (l == r) return;

    int mid = (l + r) >> 1;
    if (pos <= mid) Insert(l, mid, ls[rt], pos, x);
    else Insert(mid + 1, r, rs[rt], pos, x);
}

bool flag;

void Query(int l, int r, int rt, int L, int R, int x) {
    if (!rt) return;
    if (l > R || r < L || flag) return;
    if (L <= l && r <= R) {
        if (Min[rt] <= x) flag = true;
        return;
    }
    int mid = (l + r) >> 1;
    Query(l, mid, ls[rt], L, R, x);
    Query(mid + 1, r, rs[rt], L, R, x);
}

int main()
{
    while(scanf("%d", &op) != EOF) {
        if (op == 0) {
            tot = 0;
            mem(root, 0), mem(Min, 0), mem(ls, 0), mem(rs, 0);
        }
        else if (op == 1) {
            int x, y, c;
            sc(x), sc(y), sc(c);
            Insert(1, 1000000, root[c], y, x);
        }
        else if (op == 2) {
            int x, y1, y2;
            sc(x), sc(y1), sc(y2);
            int ans = 0;
            Rep(i, 0, 50) {
                flag = 0;
                Query(1, 1000000, root[i], y1, y2, x);
                if (flag) ans++;
            }
            pr(ans);
        }
        else break;
    }
    return 0;
}
posted @ 2018-10-16 23:29  天之道,利而不害  阅读(153)  评论(0编辑  收藏  举报