title: 题目
![[Pasted image 20220802100243.png]]
title: input
2
6
1 3 2 6 5 4
5
3 5 2 4 1
title: output
Case #1: 10
Case #2: 1
title: 思路
$$
\begin{align*}
& a[x] < a[z] < a[y] 且 x < y < z \\
& (x < y < z) \\
& == (x < y < z) + (x < z < y) - (x < z < y)\\
& == (x < *) - (x < z < y)\\
\end{align*}
$$
根据x来找, 找后面比这个数大的个数n, 求 $C^{2}_{n}$
求 $(x < z < y)$ 则把当前数当做z, 小于z的个数\*大于z的个数即可。
**小于当前数的个数: **`sum1 = sum(a[i]);`
**大于当前数的个数:** `(n - a[i]) - (i - 1 - sum1)` 前一项是所有大于当前数的个数, 后一项是之前计算过的大于当前数的个数, 作差即是后面大于该数的个数。
**(x < z < y): ** `大于当前数的个数 \* 小于当前数的个数`
**(x < *): ** `大于当前数的个数 * (大于当前数的个数 - 1) / 2`
如何快速求小于当前数的个数? 用树状数组。
title:代码
~~~ c ++
#include <iostream>
#include <cstring>
#include <queue>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
typedef pair<int, int> PII;
int readInt()
{
int t;
scanf("%d", &t);
return t;
}
//------- Coding Area ---------//
const int N = 5e5 + 10, MOD = 1e8 + 7;
int t[N], a[N], n;
int lowbit(int i)
{
return i & -i;
}
void add(int i)
{
for (i; i <= n; i += lowbit(i))
t[i]++;
}
int sum(int i)
{
int s = 0;
for (i; i; i -= lowbit(i))
s += t[i];
return s;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin >> T;
for (int kase = 1; kase <= T; kase++)
{
memset(t, 0, sizeof t);
cin >> n;
long long res = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
int sum1 = sum(a[i] - 1); // 小于当前数的个数
add(a[i]);
int t = (n - a[i]) - (i - sum1 - 1); // 大于当前数的个数
res += (long long)t * (t - 1) / 2 - (long long)sum1 * t;
res = (res % MOD + MOD) % MOD;
}
cout << "Case #" << kase << ": " << res << "\n";
}
}
~~~