The Romans have attacked again. This time they are much more than the Persians but Shapur is ready to defeat them. He says: "A lion is never afraid of a hundred sheep".
Nevertheless Shapur has to find weaknesses in the Roman army to defeat them. So he gives the army a weakness number.
In Shapur's opinion the weakness of an army is equal to the number of triplets i, j, k such that i < j < k and ai > aj > ak where ax is the power of man standing at position x. The Roman army has one special trait — powers of all the people in it are distinct.
Help Shapur find out how weak the Romans are.
The first line of input contains a single number n (3 ≤ n ≤ 106) — the number of men in Roman army. Next line contains n different positive integers ai (1 ≤ i ≤ n, 1 ≤ ai ≤ 109) — powers of men in the Roman army.
A single integer number, the weakness of the Roman army.
Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to use cout (also you may use %I64d).
3 3 2 1
1
3 2 3 1
0
4 10 8 3 1
4
4 1 5 4 3
1
题意:
给出 N (3 ~ 10 ^ 6)代表有 N 个数(1 ~ 10 ^ 9),求出能组成 i < j < k 且 num [ i ] > num [ j ] > num [ k ] 的序列一共有多少种。
思路:
树状数组 + 离散化。数最大是 10 ^ 9,而一共只可能出现 10 ^ 6 个数,故可以离散化,给每个数一个对应的编号大小。对于数列中的每一个数,都可能是中间值,如果是中间值的话,则寻找左边大于这个中间值的个数 big [ i ] 和 右边小于这个中间值的个数 small [ i ],最后将所有的 big * small 相加即为答案。维护 small 和 big 的时候,用树状数组维护即可。
AC:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
typedef long long ll;
const int MAX = 1000005;
map<int, int> m;
int num[MAX], New[MAX];
int small[MAX], big[MAX];
int bit[MAX];
int nn;
int sum(int i) {
int s = 0;
while (i > 0) {
s += bit[i];
i -= i & -i;
}
return s;
}
void add(int i, int x) {
while (i <= nn) {
bit[i] += x;
i += i & -i;
}
}
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &num[i]);
New[i] = num[i];
}
nn = 0;
sort(New + 1, New + 1 + n);
for (int i = 1; i <= n; ++i) {
if (!m[New[i]]) m[New[i]] = ++nn;
}
memset(bit, 0, sizeof(bit));
for (int i = 1; i <= n; ++i) {
big[i] = sum(nn) - sum(m[ num[i] ]);
add(m[ num[i] ], 1);
}
memset(bit, 0, sizeof(bit));
for (int i = n; i >= 1; --i) {
small[i] = sum(m[ num[i] ] - 1);
add(m[ num[i] ], 1);
}
ll res = 0;
for (int i = 1; i <= n; ++i) {
res += (ll)small[i] * (ll)big[i];
}
printf("%I64d\n", res);
return 0;
}