题目链接:传送门
一丢丢思维+bit
题意:
给一个数组,每次将数组中大于x得值替换为x,求逆序对
思路:
当把比x大得数全部替换为x之后求得逆序对是原数组中小于x得值得逆序对得数量加起来,所以用一个数组预处理一个比x小得所有的逆序对的数量,修改到某一位时,前缀和就可以了
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 10;
int a[N], b[N];
int n, m;
int cnt[N];
class bit
{
private:
int f[N];
public:
int lowbit(int x) { return x & -x; }
void add(int x){while (x <= n)f[x]++, x += lowbit(x);}
int query(int x){int ans = 0;while (x)ans += f[x], x -= lowbit(x);return ans;}
} tr;
signed main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
x++;
a[i] = b[i] = x;
}
sort(b + 1, b + n + 1);
m = unique(b + 1, b + n + 1) - b;
for (int i = 1; i <= n; i++)
{
int ind = lower_bound(b + 1, b + m + 1, a[i]) - b;
tr.add(ind);
int res = i - tr.query(ind);
cnt[a[i]] += res;
}
for (int i = 1; i <= n; i++)
cnt[i] += cnt[i - 1];
for (int i = 1; i <= n; i++)
{
cout << cnt[i - 1] << endl;
}
}