题目大意
有$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;
}