题目描述
Erwin最近对一种叫"thair"的东西巨感兴趣。。。
在含有n个整数的序列a1,a2......an中,
三个数被称作"thair"当且仅当i<j<k且ai<aj<ak
求一个序列中"thair"的个数。
输入输出格式
输入格式:
开始一个正整数n,
以后n个数a1~an。
输出格式:
"thair"的个数
输入输出样例
输入样例#1: 复制
4 2 1 3 4
输出样例#1: 复制
2
输入样例#2: 复制
5 1 2 2 3 4
输出样例#2: 复制
7
说明
对样例2的说明:
7个"thair"分别是
1 2 3 1 2 4 1 2 3 1 2 4 1 3 4 2 3 4 2 3 4 约定 30%的数据n<=100
60%的数据n<=2000
100%的数据n<=30000
大数据随机生成
0<=a[i]<=maxlongint
思路:首先看到这个题我们很容易的想到枚举每一个数,然后用该数左边比他小的数的个数乘以该数右边比他大的数的个数,然后将所有的结果相加即可,但是在这里因为他给的是大数据随机生成,所以我们按一般的方法来写是不可行的,例如他给出999999999,那么我们就需要一个数组List【999999999】,显然不存在,所以就有了离散化的方法,我们不需要开这么大的数组,我们只需要记住他们之间的大小便可以用其他数来替代,例如520,9999999,18,666,88888我们可以用2,5,1,3,4来替代,这样我们开的数组的范围就小了很多,其他的就看代码吧,具体内容在代码里进行讲解
#include<iostream>
#include<algorithm>
using namespace std;
#define lowbit(i) ((i) & (-i))
const int maxn = 30010;
struct Node{
int val;
int pos;
}node[maxn];
int cmp(Node e, Node f) {
return e.val < f.val;
}
long long n, a, ans;
int c[maxn], numGreater[maxn], numLess[maxn], List[maxn];
void update(int x) {
for (int i = x; i < maxn; i += lowbit(i)) {
c[i] += 1;
}
}
long long getSum(int x) {
long long sum = 0;
for (int i = x; i > 0; i -= lowbit(i)) {
sum += c[i];
}
return sum;
}
int main () {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> node[i].val;
node[i].pos = i;
}
//离散化
sort (node + 1, node + 1 + n, cmp); //按照值从大到小排序
for (int i = 1; i <= n; i++) {
//与上一个元素不同时,赋值为元素个数
if (i == 1 || node[i].val != node[i - 1].val) {
List[node[i].pos] = i;
} else {
//相同时直接继承
List[node[i].pos] = List[node[i - 1].pos];
}
}
//求该数左边比他小的数的个数
for (int i = 1; i <= n; i++) {
update(List[i]);
numLess[i] = getSum(List[i] - 1);
}
//必须要重置,因为后面还会用到
fill(c + 1, c + n + 1, 0);
//求该数右边比他大的数的个数,我们倒这来一遍就可以了
for (int i = n; i > 0; i--) {
update(List[i]);
numGreater[i] = n - i + 1 - getSum(List[i]);
}
//左边比他小的数的个数乘以右边比他大的数的个数
for (int i = 2; i < n; i++) {
ans += numLess[i] * numGreater[i];
}
cout << ans << endl;
}