[CF61E] Enemy is weak

[CF61E] Enemy is weak - 树状数组

Description

给定 n 个数的序列 a,求出满足 (i<j<k ,a_i > a_j > a_k) 的三元组 ((i,j,k)) 的个数

Solution

枚举中间位置 j,统计出左边更大的数的个数和右边更小的数的个数

离散化后权值树状数组即可

#include <bits/stdc++.h>
using namespace std;

#define int long long

struct BinaryIndexTree
{
    vector<int> a;
    int n;
    BinaryIndexTree(int siz)
    {
        n = siz;
        a.resize(n + 2);
    }
    int lowbit(int x)
    {
        return x & (-x);
    }
    void Add(int p, int v)
    {
        while (p <= n)
        {
            a[p] += v;
            p += lowbit(p);
        }
    }
    int Sum(int p)
    {
        int ans = 0;
        while (p)
        {
            ans += a[p];
            p -= lowbit(p);
        }
        return ans;
    }
    int More(int p)
    {
        return Sum(n) - Sum(p);
    }
    int Less(int p)
    {
        return Sum(p - 1);
    }
};

signed main()
{
    ios::sync_with_stdio(false);

    int n;
    cin >> n;

    vector<int> a(n + 2);
    for (int i = 1; i <= n; i++)
        cin >> a[i];

    map<int, int> mp;
    for (int i = 1; i <= n; i++)
        mp[a[i]]++;
    int ind = 0;
    for (auto &[x, y] : mp)
        y = ++ind;
    for (int i = 1; i <= n; i++)
        a[i] = mp[a[i]];

    BinaryIndexTree bit_left(n), bit_right(n);
    for (int i = 1; i <= n; i++)
        bit_right.Add(a[i], 1);
    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        bit_left.Add(a[i], 1);
        bit_right.Add(a[i], -1);
        ans += bit_left.More(a[i]) * bit_right.Less(a[i]);
    }
    cout << ans << endl;
}
原文地址:https://www.cnblogs.com/mollnn/p/14403696.html