B
/*计算序列 a[] 中, 当 i < j < k, a[i] < a[j]&&a[j] > a[k], (a[i]和a[k]无需比较大小)这样的子序列个数。
Input
多组输入数据:
每组数据第一行一个数n:代表序列长度为n(0<n<50000);
接下来第二行有n个数:代表序列元素的值a[i](0<=a[i]<50000,且任意2个元素的值不相同)。
Output
对于每组数据输出符合条件的子序列的个数,每个输出占一行。
Sample Input
5
1 3 5 2 4
——————————————————————
解题思路:
结构体 node。vel表示这个数本身大小node。id表示第几次输入(原来的顺序)
把结构体数组从小到大排列;c[i]存放比第I个数小的数字的个数;
因为已经排完序,所以get_sum(n)直接表示所有比此时需要比较的数小的数;
get_sum(node[i].id)表示当其按照原顺序排列时其前面比它小的数的个数;
所以结果sum += (get_sum(n) - get_sum(num[j].id)) * get_sum(num[j].id - 1 );
*/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define maxn 50000 + 5
using namespace std;
int n;
int c[maxn];
struct node
{
int vel;
int id;
} ;
int lowbit( int i)
{
return i &(-i);
}
void add(int i, int j)
{
while( i <= n)
{
c[i] += j;
i += lowbit(i);
}
}
int get_sum(int i)
{
int ans = 0;
while( i > 0)
{
ans += c[i];
i -= lowbit(i);
}
return ans;
}
int cmp(node x, node y)
{
return x.vel <y.vel;
}
int main(void)
{ int sum = 0;
while(scanf("%d",&n) != EOF)
{ node num[maxn];
sum = 0;
for( int i = 1; i <= n; i++)
{
scanf("%d",&num[i].vel);
num[i].id = i;
}
sort(num+1, num+n+1,cmp);
memset(c,0,sizeof(c));
add(num[1].id,1);
for ( int j = 2; j <= n ; j++)
{ //cout<<get_sum(num[j].id)<<" "<<get_sum(n)<<" ";
//cout<<num[j].id<<" ";
//cout<<(get_sum(n) - get_sum(num[j].id)) * get_sum(num[j].id - 1 )<<endl;
sum += (get_sum(n) - get_sum(num[j].id)) * get_sum(num[j].id - 1 );
add(num[j].id,1);
}
printf("%d\n", sum);
}
}