题目就是赤裸裸的三维偏序,所以用CDQ+树状数组可以比较轻松的解决,但是还是树套树好想QAQ
CDQ+树状数组
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; const ll maxn = 200000 + 100; struct node { int a, b, c, num, val; }q[maxn], w[maxn]; bool cmp(node x, node y) { return x.a == y.a ? (x.b == y.b ? x.c < y.c : x.b < y.b) : x.a < y.a; } int sum[maxn], ans[maxn]; int n, k; int lowbit(int x) { return x & -x; } void add(int x, int val) { while (x <= k) { sum[x] += val; x += lowbit(x); } } int query(int x) { int ans = 0; while (x > 0) { ans += sum[x]; x -= lowbit(x); } return ans; } void CDQ(int l, int r) { if (l == r)return; int mid = l + r >> 1; CDQ(l, mid); CDQ(mid + 1, r); int L = l, R = mid + 1, cnt = l; while (L <= mid && R <= r) { if (w[L].b <= w[R].b)add(w[L].c, w[L].num), q[cnt++] = w[L++]; else w[R].val += query(w[R].c), q[cnt++] = w[R++]; } while (L <= mid)add(w[L].c, w[L].num), q[cnt++] = w[L++]; while (R <= r)w[R].val += query(w[R].c), q[cnt++] = w[R++]; for (int i = l; i <= mid; i++)add(w[i].c, -w[i].num); for (int i = l; i <= r; i++)w[i] = q[i]; } int main() { scanf("%d%d", &n, &k); for (int i = 1; i <= n; i++) scanf("%d%d%d", &q[i].a, &q[i].b, &q[i].c), q[i].num = 1; sort(q + 1, q + 1 + n, cmp); int cnt = 1; w[1] = q[1]; for (int i = 2; i <= n; i++) { if (q[i].a == w[cnt].a&&q[i].b == w[cnt].b&&q[i].c == w[cnt].c)w[cnt].num++; else w[++cnt] = q[i]; } CDQ(1, cnt); for (int i = 1; i <= cnt; i++) ans[w[i].val + w[i].num - 1] += w[i].num; for (int i = 0; i < n; i++) printf("%d ", ans[i]); }
树套树(树状数组套线段树)
因为空间有限,线段树要动态开点且要写成链表QAQ。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned long long ull; 5 const ll maxn = 200000 + 100; 6 struct node { 7 int a, b, c, num, val; 8 }q[maxn], w[maxn]; 9 bool cmp(node x, node y) { 10 return x.a == y.a ? (x.b == y.b ? x.c < y.c : x.b < y.b) : x.a < y.a; 11 } 12 int n, k; 13 int ans[maxn]; 14 struct seg { 15 struct node { 16 int val; 17 node *ls, *rs; 18 node() { val = 0; ls = rs = NULL; } 19 }; 20 node *root; 21 seg() { 22 root = NULL; 23 } 24 void update(node *&x, int pos, int val, int l, int r) { 25 if (!x)x = new node(); 26 if (l == r) { 27 x->val += val; 28 return; 29 } 30 int mid = l + r >> 1; 31 if (pos <= mid)update(x->ls, pos, val, l, mid); 32 else update(x->rs, pos, val, mid + 1, r); 33 x->val = (x->ls ? x->ls->val : 0) + (x->rs ? x->rs->val : 0); 34 } 35 int query(node *x, int L, int R, int l, int r) { 36 if (!x)return 0; 37 if (L <= l && r <= R) 38 return x->val; 39 int mid = l + r >> 1, ans = 0; 40 if (L <= mid)ans += query(x->ls, L, R, l, mid); 41 if (R > mid)ans += query(x->rs, L, R, mid + 1, r); 42 return ans; 43 } 44 }T[maxn]; 45 int lowbit(int x) { 46 return x & -x; 47 } 48 void add(int x, int q, int val) { 49 while (x <= k) { 50 T[x].update(T[x].root, q, val, 1, k); 51 x += lowbit(x); 52 } 53 } 54 int query(int x, int q) { 55 int ans = 0; 56 while (x > 0) { 57 ans += T[x].query(T[x].root, 1, q, 1, k); 58 x -= lowbit(x); 59 } 60 return ans; 61 } 62 int main() { 63 scanf("%d%d", &n, &k); 64 for (int i = 1; i <= n; i++) 65 scanf("%d%d%d", &q[i].a, &q[i].b, &q[i].c), q[i].num = 1; 66 sort(q + 1, q + 1 + n, cmp); 67 int cnt = 1; 68 w[1] = q[1]; 69 for (int i = 2; i <= n; i++) { 70 if (q[i].a == w[cnt].a&&q[i].b == w[cnt].b&&q[i].c == w[cnt].c)w[cnt].num++; 71 else w[++cnt] = q[i]; 72 } 73 for (int i = 1; i <= cnt; i++) { 74 add(w[i].b, w[i].c, w[i].num); 75 int p = query(w[i].b, w[i].c); 76 ans[p] += w[i].num; 77 } 78 for (int i = 1; i <= n; i++) 79 printf("%d ", ans[i]); 80 }