于是这篇文章又接上了上一篇讲LIS的

又是一道维护线性具有单调性的序列的题,我们这次又双用上我们的$\log n$数据结构——树状数组。

很明显,对于每个节点$i$($1<i<n$),我们需要维护的就是两端比它大(或小)的数据的个数,这里用上树状数组,可以将插入的时间复杂度降低到$\log n$,可以显著优化此类需要频繁插入数据的情况。

#include <bits/stdc++.h>
#define MAXN 200001
using namespace std;
using ll = long long;

int n;

ll tree[MAXN];
ll ys[MAXN];
ll l[MAXN],r[MAXN];

ll ansa,ansb;

int lowbit(int x) {
    return x & -x;
}

void add(int x) {
    for (int i = x; i <= n; i += lowbit(i))
        ++tree[i];
}

ll query(int x) {
    ll ret = 0;
    for (int i = x; i; i -= lowbit(i))
        ret += tree[i];

    return ret;
}

int main() {
    cin >> n;

    for (int i = 1; i <= n; ++i)
        cin >> ys[i];

    for (int i = 1; i <= n; ++i) {
        l[i] = query(ys[i]);
        add(ys[i]);
    }

    memset(tree, 0, sizeof(tree));

    for (int i = n; i >= 1; --i) {
        r[i] = query(ys[i]);
        add(ys[i]);
    }

    for (int i = 2; i < n ; ++i) {
        ansa += (i - l[i] -1) * (n - i - r[i]);
        ansb += l[i] * r[i];
    }

    cout << ansa << ' ' << ansb << endl;

    return 0;
}
Last modification:May 4, 2019
博客维护不易,如果你觉得我的文章有用,请随意赞赏