题意
求四元组 ( a , b , c , d ) (a,b,c,d) (a,b,c,d),满足 a < b ; c < d ; S a < S b ; S c > S d a<b;c<d;S_a<S_b;S_c>S_d a<b;c<d;Sa<Sb;Sc>Sd, a b c d abcd abcd不相等。
思路
若能相等,答案即顺序对
∗
*
∗逆序对,否则考虑以下重复点的四种情况:
a
=
c
a=c
a=c
(
a
=
c
)
<
b
,
d
(a=c)<b,d
(a=c)<b,d且
S
d
<
S
a
=
c
<
S
b
S_d<S_{a=c}<S_b
Sd<Sa=c<Sb
a
=
d
a=d
a=d
c
<
(
a
=
d
)
<
b
c<(a=d)<b
c<(a=d)<b且
S
a
=
d
<
S
b
,
S
c
S_{a=d}<S_{b},S_c
Sa=d<Sb,Sc
b
=
c
b=c
b=c
a
<
(
b
=
c
)
<
d
a<(b=c)<d
a<(b=c)<d且
S
b
=
c
>
S
a
,
d
S_{b=c}>S_{a,d}
Sb=c>Sa,d
b
=
d
b=d
b=d
a
,
c
<
(
b
=
d
)
a,c<(b=d)
a,c<(b=d)且
S
a
<
S
b
=
d
<
S
c
S_a<S_{b=d}<S_c
Sa<Sb=d<Sc
用树状数组求解。(我真是超级无敌大傻逼,连逆序对都不会求)
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
int n;
long long ans, p, q;
long long t[100001], a[100001], b[100001], rs[100001], rb[100001], ls[100001], lb[100001];
void add(int x, int val) {
for (; x <= n; x += x & -x)
t[x] += val;
}
long long query(int x) {
long long res = 0;
for (; x; x -= x & -x)
res += t[x];
return res;
}
void init() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]), b[i] = a[i];
std::sort(b + 1, b + n + 1);
int m = std::unique(b + 1, b + n + 1) - b - 1;
for (int i = 1; i <= n; i++)
a[i] = std::lower_bound(b + 1, b + m + 1, a[i]) - b;
}
int main() {
init();
for (int i = n; i >= 1; i--)
p += rs[i] = query(a[i] - 1), rb[i] = query(n) - query(a[i]), add(a[i], 1);
memset(t, 0, sizeof(t));
for (int i = 1; i <= n; i++)
q += ls[i] = query(a[i] - 1), lb[i] = query(n) - query(a[i]), add(a[i], 1);
ans = p * q;
for (int i = 1; i <= n; i++)
ans -= rb[i] * rs[i] + rb[i] * lb[i] + rs[i] * ls[i] + lb[i] * ls[i];
printf("%lld", ans);
}