Topic Link: "http://acm.split.hdu.edu.cn/showproblem.php?pid=5517"
Test instructions: DefiningMulti_set A<a, D>,b<c, D, E>,c<x, Y, z>, give a, B, define C = A * B =={?A,C,D?∣?A,B?∈a, ? C,d ,e ? ∈b and b=e< Span id= "mathjax-span-63" class= "Mo" >} 。after finding C, ask for an element in C T[i]<a, B, c> if there is an element tmp<x, Y, z> make x >= a&&y > =b&&z >= C & & T! = tmp; If ans++ is not present, output ans.
Exercises
First of all, we want to prune and go to the weight, join the set a in the presence of <1, 3>,<2, 3>,<3, 3>, <4, 3>,<4, 3> then just keep <4,3> on it, and record the number. Because the previous number can find an element larger than it. After we find C, we still have to go to the C-weight. So the problem is to ask whether an element of C is larger than its element. Because this problem in the B set inside c,d, very small in the generated C y,z is also very small, are less than 1000, then we can use a two-dimensional tree array to do. First, C is sorted from large to small, and only y,z values are recorded in the tree array. We enumerate the amount of each element in C, first query (1001-y, 1001-z), and then in the update (1001-Y, 1001-z), should be from large to small sort, so the next element of the X value must be less than equal to the previous element's X value, s if the query is not 0, then there must be an element is Larger than it. We can directly set CDQ division of the three-dimensional partial-order template, in order to maintain the value.
Tree-like array:
#include <bits/stdc++.h>using namespace Std;typedef long long ll;const int MAXN = 1e5 + 15;int ic, N, M;struct point{ int x, y, Z; LL W; Point () {} point (int x, int y, int z, LL W): X (x), Y (y), Z (z), W (w) {} BOOL operator < (const point& T) const {if (x! = t.x) return T.x < x; if (Y! = t.y) return T.y < Y; return t.z < Z; } bool operator = = (Const point T) Const {return (x = = T.x && y = = T.y && z = = t.z); }} p[maxn];int T[maxn], c[maxn];int tbit[1050][1050];int low_bit (int x) {return x & x;} void Bit_add (int x, int y, int val) {for (int i = x; i <= 1001; i + = Low_bit (i)) for (int j = y; J <= 1001; J + = Low_bit (j)) Tbit[i][j] + = val; int bit_sum (int x, int y) {int ret = 0; for (int i = x; i; i-= Low_bit (i)) for (int j = y; j; J-= Low_bit (j)) ret + = Tbit[i][j]; return ret;} int main () {scanf ("%d", &ic); for (int cs = 1; CS <= IC; cs++) {scanf ("%d%d", &n, &m); memset (t, 0, sizeof (t)); for (int i = 1; I <= N; i++) {int A, B; scanf ("%d%d", &a, &b); if (a > T[b]) t[b] = A, c[b] = 1; else if (a = = T[b]) c[b]++; } int tmp = 0; for (int i = 1; I <= M; i++) {int A, b, C; scanf ("%d%d%d", &a, &b, &c); if (T[c]) p[++tmp] = Point (T[c], A, B, (LL) c[c]); } sort (p + 1, p + 1 + tmp); N = 1; for (int i = 2; I <= tmp; i++) {if (p[i] = = P[n]) P[N].W + = P[I].W; else p[++n] = p[i]; } LL ans = 0; memset (tbit, 0, sizeof (tbit)); for (int i = 1; I <= N; i++) {if (! Bit_sum (1001-P[I].Y, 1001-p[i].z)) ans + = P[I].W; Bit_add (1001-p[i].y, 1001-p[i].z, 1); } printf ("Case #%d:%lld\n", cs, ans); } return 0;}
three-dimensional partial order:
#include <bits/stdc++.h>using namespace Std;typedef long long ll;const int MAXN = 1e5 + 15;int cs, N, M;int T[MAXN], C[MAXN]; LL W[MAXN], ans[maxn];struct edge{int x, y, z, id; LL W; Edge () {} edge (int x, int y, int z, int id, LL W): X (x), Y (y), Z (z), ID (ID), W (w) {} BOOL operator < (const Edge & T) const {return Z < t.z; } bool operator = = (Const Edge & T) const {return t.x = = x && t.y = = y && t.z = = Z; }} B[MAXN], P[MAXN], T[maxn];bool cmpx (Edge &a, Edge &b) {if (a.x = b.x && a.y = b.y && A.z = = B.Z) return a.id < b.id; else if (a.x = = b.x && a.y = = b.y) return a.z < b.z; else if (a.x = = b.x) return A.Y < b.y; else return a.x < b.x;} BOOL Cmpy (Edge &a, Edge &b) {if (a.y = = B.y && a.z = = b.z) return a.id < b.id; else if (a.y = = b.y) return a.z < b.z; else return A.Y < B.Y;} --------------------------------------------------------//tree array int C[MAXN], maxz = 1001;inline int lowbit (int x) {RET Urn x & (-X);} void Add (int x, int val) {while (x <= maxz) c[x] + = val, x + = Lowbit (x);} int get_sum (int x) {int ret = 0; while (x > 0) ret + = C[x], X-= Lowbit (x); return ret;} -------------------------------------------------void Cdq (int l, int r) {if (L = = r) return; int mid = (L + r)/2; CDQ (L, mid), CDQ (mid + 1, R); for (int i = l; I <= R; i++) T[i] = P[i]; Sort (T + L, T + mid + 1, cmpy), sort (T + mid + 1, T + R + 1, cmpy); int a1 = L, a2 = mid + 1; for (int i = l; I <= R; i++) {if (A1 = = mid + 1) ans[t[a2].id] + = Get_sum (t[a2].z), a2++; else if (A2 = = R + 1) Add (t[a1].z, 1), a1++; else if (t[a1].y <= t[a2].y) Add (t[a1].z, 1), a1++; else Ans[t[a2].id] + = Get_sum (t[a2].z), a2++; } for (int i = l; I <= mid; i++) Add (t[i].z,-1);}int main () {scanf ("%d", &cs); for (int ic = 1; IC <= CS; ic++) {memset (t, 0, sizeof (t)); memset (ans, 0, sizeof (ans)); scanf ("%d%d", &n, &m); for (int i = 1; I <= N; i++) {int A, B; scanf ("%d%d", &a, &b); if (a > T[b]) t[b] = A, c[b] = 1; else if (a = = T[b]) c[b]++; } int tmp = 0; for (int i = 1; I <= M; i++) {int A, b, C; scanf ("%d%d%d", &a, &b, &c); if (T[c]) ++tmp, p[tmp] = Edge (T[c], a, B, I, (LL) c[c]); } sort (p + 1, p + 1 + tmp, CMPX); N = 1; for (int i = 2; I <= tmp; i++) {if (p[i] = = P[n]) P[N].W + = P[I].W; else p[++n] = p[i]; } if (N <= 1) {printf ("Case #%d:0\n", ++ic); Continue } for (int i = 1; I <= N; i++) {p[i].x = 100001-p[i].x;P[i].y = 1001-P[I].Y; P[i].z = 1001-p[i].z; } for (int i = 1; I <= N; i++) {p[i].id = i; W[i] = P[I].W; } sort (p + 1, p + 1 + N, cmpx); CDQ (1, N); P[n + 1].x =-1; for (int i = N; I >= 1; i--) {if (p[i].x = = p[i + 1].x && p[i].y = p[i + 1].y && P[i] . z = = p[i + 1].z) ans[p[i].id] = ans[p[i + 1].id]; } LL ret = 0; for (int i = 1; I <= N; i++) if (!ans[i]) ret + = W[i]; printf ("Case #%d:%lld\n", IC, ret); } return 0;}
HDU 5517 "Two-dimensional tree-like array///three-dimensional partial order problem"