luogu3810 【模板】三维偏序(陌上花开)

题目大意

  有$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;
}

  

原文地址:https://www.cnblogs.com/headboy2002/p/9375413.html