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;
}