题解 | #小红的子序列逆序对#

小红的子序列逆序对

https://www.nowcoder.com/practice/189a109747604763932024984f856d99

对于一个逆序对 i j 来说,其在子序列中出现的次数是固定的,是 2^(n-2),因为对于 n 个数而言,i 和 j 必须出现在逆序对中,而其他数都可以出现或者不出现,所以每个逆序对都会出现 2^(n-2) 次,答案就是逆序对数量乘 2^(n-2)

而求逆序对数量很简单了,实现方法很多,这里给一个树状数组实现的方法

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5;
const int mod = 1e9 + 7;
int __t = 1, n, a[N], s[N], f[N] = {1, 1, 1};
void update(int x, int y) {
    for (; x <= 1e5; x += x & -x)
        s[x] = (s[x] + y) % mod;
}
int query(int x) {
    int res = 0;
    for (; x; x -= x & -x)
        res = (res + s[x]) % mod;
    return res;
}
void solve() {
    for (int i = 3; i < N; ++i)
        f[i] = f[i - 1] * 2 % mod;
    cin >> n;
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
        ans = (ans + (query(1e5) - query(a[i]) + mod) % mod) % mod;
        update(a[i], 1);
    }
    cout << ans * f[n] % mod << '\n';
}
int32_t main() {
#ifdef ONLINE_JUDGE
    ios::sync_with_stdio(false);
    cin.tie(0);
#endif
    // cin >> __t;
    while (__t--)
        solve();
    return 0;
}

全部评论

相关推荐

10-17 10:05
已编辑
北华大学 全栈开发
牛客872465272号:掉头发了哥
点赞 评论 收藏
分享
11-05 07:29
贵州大学 Java
点赞 评论 收藏
分享
评论
2
1
分享
牛客网
牛客企业服务