#include #include #include #include #include #include //#include #include #include using namespace std; typedef long long LL; typedef pair pint; typedef pair pll; #define fi first #define se second typedef map mapint; typedef vector vint; typedef vector vintp; #define rep(i,j,k) for (int i = (j);i <= (k);i ++) #define repd(i,j,k) for (int i = (j);i >= (k);i --) #define ran2 (rand() % 32000 * 32000 + rand() % 32000) #define pb push_back #define mp make_pair #define SIZE(i) ((int)(i.size())) #define mx 502000 int m,n,j,k,l,i,o,p,__t; char ch; void read(int &a){ for (ch = getchar();(ch < '0' || ch > '9') && (ch != '-');ch = getchar()); if (ch == '-') a = 0,__t = -1; else a = ch - '0',__t = 1; for (ch = getchar();ch >= '0' && ch <= '9';ch = getchar()) a = a * 10 + ch - '0'; a *= __t; } void get_next_char() { for (ch = getchar(); ch != 'I' && ch != 'Q' && ch != 'D'; ch = getchar()); } struct Coor { int x[2]; }; //A query event struct Query { int kind, id, tag; Coor coor[2]; } g_q[mx]; Coor matrix[mx][2]; int query_matrix_tot; Coor query_matrix[mx][2]; int ans[mx]; int discrete[2][mx], tot_dis[2]; //Binary index tree struct Tree_array { int f[mx * 2]; void clear() { memset(f, 0, sizeof f); } void add(int P, int i) { for (; P < mx; P += (P & (-P))) f[P] += i; } int calc(int P) { int ret = 0; for (; P; P -= P & (-P)) ret += f[P]; return ret; } } tree_array; void add(int id, int n) { discrete[id][++ tot_dis[id]] = n; } //Splay struct Balance_tree { int T, last_point; int S[mx * 10][2], size[mx * 10]; int Fa[mx * 10], num[mx * 10]; void add_point(int &root, int N) { if (root == 0) { root = ++ T; size[root] = 1; num[root] = N; Fa[root] = last_point; S[T][0] = S[T][1] = 0; return; } last_point = root; if (num[root] >= N) add_point(S[root][0], N); else add_point(S[root][1], N); size[root] ++; } void update(int P) { size[P] = size[S[P][0]] + size[S[P][1]] + 1; } void set_child(int fa, bool s, int son) { S[fa][s] = son; if (son != 0) Fa[son] = fa; } void rotate(int P) { bool s = (S[Fa[P]][1] == P); int fa = Fa[P]; set_child(fa, s, S[P][!s]); if (Fa[fa]) { set_child(Fa[fa], S[Fa[fa]][1] == fa, P); } else Fa[P] = 0; set_child(P, !s, fa); update(fa); update(P); } void splay(int P) { for (; Fa[P] != 0; ) { if (Fa[Fa[P]] == 0) { rotate(P); return; } if ((S[Fa[Fa[P]]][0] == Fa[P]) ^ (S[Fa[P]][0] == P)) rotate(P), rotate(P); else rotate(Fa[P]), rotate(P); } } void insert_point(int &root, int N) { last_point = 0; add_point(root, N); root = T; splay(T); } void del_point(int &root, int N) { if (num[root] == N) { if (size[root] == 1) { root = 0; return; } bool s = 0; if (S[root][0] == 0) s = 1; int t = S[root][s]; rotate(t); del_point(S[t][!s], N); size[t] --; root = t; return; } bool s = num[root] <= N; del_point(S[root][s], N); size[root] --; root = root; } void delete_point(int &root, int N) { int temp = root; del_point(temp, N); root = temp; splay(root); } int calc(int P, int maxi) { if (P == 0) return 0; if (num[P] > maxi) return calc(S[P][0], maxi); int ret = size[S[P][0]] + 1; return ret + calc(S[P][1], maxi); } void clear() { memset(S, 0, sizeof S); memset(size, 0, sizeof size); memset(Fa, 0, sizeof Fa); T = 0; } } splay; //Binary index tree with a splay in it struct Segment_tree { int Root[mx * 4]; void insert(int P, int l, int r, int x, int y, int n, int q = 0) { for (; x <= r; x += (x & (-x))) { if (q == 0) { splay.insert_point(Root[x], n); } else splay.delete_point(Root[x], n); } /*if (q == 0) { splay.insert_point(Root[P], n); } else splay.delete_point(Root[P], n); if (l == r) return; int mid = (l + r) / 2; if (x <= mid) insert(P * 2, l, mid, min(x, mid + 1), min(y, mid), n, q); else insert(P * 2 + 1, mid + 1, r, max(x, mid + 1), max(y, mid), n, q); */ } int calc(int P, int l, int r, int x, int y, int n) { int ret = 0; for (; y > 0; y -= (y & (-y))) { ret += splay.calc(Root[y], n); } return ret; /*if (l > y || r < x) return 0; if (l == x && r == y) { return splay.calc(Root[P], n); } int mid = (l + r) / 2; return calc(P * 2, l, mid, min(x, mid + 1), min(y, mid), n) + calc(P * 2 + 1, mid + 1, r, max(x, mid + 1), max(y, mid), n); */ } void clear() { memset(Root, 0, sizeof Root); } } segment_tree; void judge_query(int &u, int &v, int idx, int idy) { if (idx == 0 && idy == 1) v = tot_dis[1] - v + 1; if (idx == 1) { u = tot_dis[0] - u + 1; if (idy == 1) v = tot_dis[1] - v + 1; } } void solve2(int idx, int idy) { splay.clear(); segment_tree.clear(); int matrix_id = 0, temp = 0; rep(i, 1, m) { if (g_q[i].kind == 0) { int u = matrix[++ matrix_id][idx ^ 1].x[0]; int v = matrix[matrix_id][idy ^ 1].x[1]; judge_query(u, v, idx, idy); //cout << "insert" << u << ' ' << v << endl; segment_tree.insert(1, 1, tot_dis[0], u, u, v); } else if (g_q[i].kind == 1) { int u = matrix[g_q[i].id][idx ^ 1].x[0]; int v = matrix[g_q[i].id][idy ^ 1].x[1]; judge_query(u, v, idx, idy); //cout << "delete" << u << ' ' << v << endl; segment_tree.insert(1, 1, tot_dis[0], u, u, v, 1); } else { ++ temp; int u = query_matrix[temp][idx].x[0]; int v = query_matrix[temp][idy].x[1]; judge_query(u, v, idx, idy); ans[g_q[i].tag] += segment_tree.calc(1, 1, tot_dis[0], 1, u - 1, v - 1); } } } void solve(int id, int pos) { tree_array.clear(); int matrix_id = 0, temp = 0; rep(i, 1, m) { if (g_q[i].kind == 0) { int u = matrix[++ matrix_id][(pos == 1) ? (1) : (0)].x[id]; tree_array.add(u, 1); } else if (g_q[i].kind == 1) { int u = matrix[g_q[i].id][(pos == 1) ? (1) : (0)].x[id]; tree_array.add(u, -1); } else { ++ temp; int u = query_matrix[temp][(pos == 1) ? (0) : (1)].x[id]; if (pos == 1) ans[g_q[i].tag] -= tree_array.calc(u - 1); else ans[g_q[i].tag] -= tree_array.calc(max(tot_dis[0], tot_dis[1]) + 1) - tree_array.calc(u); } } } int main(){ read(m); int dele = 0; rep(i, 1, m) { get_next_char(); if (ch == 'I') { g_q[i].kind = 0; read(g_q[i].coor[0].x[0]); read(g_q[i].coor[0].x[1]); read(g_q[i].coor[1].x[0]); read(g_q[i].coor[1].x[1]); matrix[++ n][0] = g_q[i].coor[0]; matrix[n][1] = g_q[i].coor[1]; add(0, matrix[n][0].x[0]); add(0, matrix[n][1].x[0]); add(1, matrix[n][0].x[1]); add(1, matrix[n][1].x[1]); } else if (ch == 'D') { g_q[i].kind = 1; read(g_q[i].id); dele ++; } else { g_q[i].kind = 2; g_q[i].tag = ++ o; ++ query_matrix_tot; read(query_matrix[o][0].x[0]); read(query_matrix[o][0].x[1]); read(query_matrix[o][1].x[0]); read(query_matrix[o][1].x[1]); add(0, query_matrix[o][0].x[0]); add(0, query_matrix[o][1].x[0]); add(1, query_matrix[o][0].x[1]); add(1, query_matrix[o][1].x[1]); ans[o] = n - dele; } } sort(discrete[0] + 1, discrete[0] + 1 + tot_dis[0]); sort(discrete[1] + 1, discrete[1] + 1 + tot_dis[1]); tot_dis[0] = unique(discrete[0] + 1, discrete[0] + 1 + tot_dis[0]) - discrete[0] - 1; tot_dis[1] = unique(discrete[1] + 1, discrete[1] + 1 + tot_dis[1]) - discrete[1] - 1; rep(i, 1, n) { matrix[i][0].x[0] = lower_bound(discrete[0] + 1, discrete[0] + 1 + tot_dis[0], matrix[i][0].x[0]) - discrete[0]; matrix[i][1].x[0] = lower_bound(discrete[0] + 1, discrete[0] + 1 + tot_dis[0], matrix[i][1].x[0]) - discrete[0]; matrix[i][0].x[1] = lower_bound(discrete[1] + 1, discrete[1] + 1 + tot_dis[1], matrix[i][0].x[1]) - discrete[1]; matrix[i][1].x[1] = lower_bound(discrete[1] + 1, discrete[1] + 1 + tot_dis[1], matrix[i][1].x[1]) - discrete[1]; } rep(i, 1, query_matrix_tot) { query_matrix[i][0].x[0] = lower_bound(discrete[0] + 1, discrete[0] + 1 + tot_dis[0], query_matrix[i][0].x[0]) - discrete[0]; query_matrix[i][1].x[0] = lower_bound(discrete[0] + 1, discrete[0] + 1 + tot_dis[0], query_matrix[i][1].x[0]) - discrete[0]; query_matrix[i][0].x[1] = lower_bound(discrete[1] + 1, discrete[1] + 1 + tot_dis[1], query_matrix[i][0].x[1]) - discrete[1]; query_matrix[i][1].x[1] = lower_bound(discrete[1] + 1, discrete[1] + 1 + tot_dis[1], query_matrix[i][1].x[1]) - discrete[1]; } solve(0, 1); solve(0, -1); solve(1, 1); solve(1, -1); solve2(0, 0); solve2(0, 1); solve2(1, 0); solve2(1, 1); rep(i, 1, o) printf("%d\n", ans[i]); }