LYBAKIOI @ 2022-10-06 16:10:54
#include <bits/stdc++.h>
#define int long long
using namespace std;
int read() {
int x = 0, k = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') k = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * k;
}
#define N 500005
struct node {
int x, id;
friend bool operator < (const node a, const node b) {
return a.x < b.x;
}
} t[N];
struct segt {
int l, r, dat;
} a[N << 2];
namespace segment_tree {
void build(int p, int l, int r) {
a[p].l = l; a[p].r = r;
if (l == r) return ;
int mid = l + r >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
}
int query(int p, int l, int r) {
if (a[p].l >= l && a[p].r <= r) return a[p].dat;
int mid = a[p].l + a[p].r >> 1, sum = 0;
if (l <= mid) sum += query(p << 1, l, r);
if (r > mid) sum += query(p << 1 | 1, l, r);
return sum;
}
void update(int p, int w, int x) {
if (a[p].l == w && a[p].r == w) {
a[p].dat += x; return ;
}
int mid = a[p].l + a[p].r >> 1;
if (w <= mid) update(p << 1, w, x);
else update(p << 1 | 1, w, x);
a[p].dat = a[p << 1].dat + a[p << 1 | 1].dat;
}
}
using namespace segment_tree;
int n, d[N];
long long ans;
signed main() {
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
n = read();
for (int i = 1; i <= n; i++)
t[i] = {read(), i};
sort(t + 1, t + n + 1);
for (int i = 1; i <= n; i++)
d[t[i].id] = i;
build(1, 1, n);
for (int i = 1; i <= n; i++) {
ans += query(1, d[i] + 1, n);
update(1, d[i], 1);
}
printf("%lld", ans);
}
rt,第 6 个点就错,发现输出比答案大了 2。
by bamboo12345 @ 2022-10-06 16:26:09
@LYBAKIOI 可能有重复数字,你这样统计的话相同的也会计算
by LYBAKIOI @ 2022-10-06 16:38:38
感谢楼上!sort是不稳定排序,可能会改变相同元素的相对位置(恍然大雾)。
struct node {
int x, id;
friend bool operator < (const node a, const node b) {
if (a.x == b.x) return a.id < b.id;
return a.x < b.x;
}
} t[N];
by Kniqht @ 2022-10-07 21:46:32
大佬们都不屑于用树状数组/kk
by x1uc @ 2022-10-30 09:38:13
感谢!