题目大意
有$n$个元素,第$i$个元素有$a_i,b_i,c_i$三个属性,设$f(i)$为$a_j<a_i,b_j<b_i,c_j<c_i$同时满足的数量。对于$din [0,n)$,求$f(i)=d$的数量。
思路
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAX_ELEMENT = 100010, MAX_MAXVAL = 200010; int TotEle, MaxVal; int F[MAX_MAXVAL]; struct Element { int A, B, C; bool operator == (const Element& a) const { return A == a.A && B == a.B && C == a.C; } bool operator < (const Element& a) const { return A != a.A ? A < a.A : B != a.B ? B < a.B : C < a.C; } }_eles[MAX_ELEMENT];//elements struct RangeTree { private: struct Node { Node *LeftSon, *RightSon; int Cnt; Node():LeftSon(NULL), RightSon(NULL), Cnt(0){} }*Root; void Update(Node *&cur, int l, int r, int p, int delta) { if (!cur) cur = new Node(); cur->Cnt += delta; if (l == r) return; int mid = (l + r) / 2; if (p <= mid) Update(cur->LeftSon, l, mid, p, delta); if (p > mid) Update(cur->RightSon, mid + 1, r, p, delta); } int Query(Node *cur, int sl, int sr, int al, int ar) { if (!cur) return 0; if (al <= sl && sr <= ar) return cur->Cnt; int ans = 0, mid = (sl + sr) / 2; if (al <= mid) ans += Query(cur->LeftSon, sl, mid, al, ar); if (ar > mid) ans += Query(cur->RightSon, mid + 1, sr, al, ar); return ans; } public: RangeTree():Root(NULL){} void operator += (int p) { Update(Root, 1, MaxVal, p, 1); } int Query(int l, int r) { return Query(Root, 1, MaxVal, l, r); } }; struct BIT { private: RangeTree C[MAX_MAXVAL]; int N; int Lowbit(int x) { return x & -x; } public: void Init(int n) { N = n; } void Update(int p, int delta) { while (p <= N) { C[p] += delta; p += Lowbit(p); } } int Query(int p, int qKey) { int ans = 0; while (p > 0) { ans += C[p].Query(1, qKey); p -= Lowbit(p); } return ans; } }g; void Solve() { sort(_eles + 1, _eles + TotEle + 1); int prevCnt = 1; for (int i = 1; i <= TotEle; i++) { if (_eles[i] == _eles[i + 1]) { prevCnt++; g.Update(_eles[i].B, _eles[i].C); continue; } F[g.Query(_eles[i].B, _eles[i].C)] += prevCnt; g.Update(_eles[i].B, _eles[i].C); prevCnt = 1; } } int main() { scanf("%d%d", &TotEle, &MaxVal); g.Init(MaxVal); for (int i = 1; i <= TotEle; i++) scanf("%d%d%d", &_eles[i].A, &_eles[i].B, &_eles[i].C); Solve(); for (int i = 0; i <= TotEle - 1; i++) printf("%d ", F[i]); return 0; }