洛谷P1637 三元上升子序列Thair(树状数组)

来源:互联网 发布:徐州共享网络玩家 编辑:程序博客网 时间:2024/06/05 14:09

Description

daming最近对一种叫"thair"的东西巨感兴趣。。。

在含有 n个整数的序列a1,a2......an中,

三个数被称作"thair"当且仅当i<j<k且ai<aj<ak

求一个序列中"thair"的个数。

Input

开始一个正整数n,

以后n个数a1~an

30%的数据n<=100

60%的数据n<=2000

100%的数据n<=30000

0<=a[i]<=maxlongint

Output

"thair"的个数

Sample Input

Input I
4
2 1 3 4
Input II
5
1 2 2 3 4

Sample Output

Output I
2
Output II
7

HINT

对样例2的说明:

7个"thair"分别是

1 2 3

1 2 4

1 2 3

1 2 4

1 3 4

2 3 4

2 3 4

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;long long map[30001],f[30001],n,mi[30001],ma[30001],ans=0,i;struct point{    int position,value;}a[30001];void build(long long x){    while(x<=n)    {        f[x]++;        x+=x&-x;    }}long long query(long long x){    long long sum=0;    while(x)    {        sum+=f[x];        x-=x&-x;    }    return sum;}bool cmp(const point &a,const point &b){    return a.value<b.value;}bool cmp2(const point &a,const point &b){    return a.value>b.value;}int main(){    scanf("%lld",&n);    for(i=1;i<=n;i++)    {        scanf("%lld",&a[i].value);a[i].position=i;    }    sort(a+1,a+n+1,cmp);     for(i=1;i<=n;i++)    {        if(a[i].value==a[i-1].value) map[a[i].position]=map[a[i-1].position];        else map[a[i].position]=i;    }    for(i=1;i<=n;i++)    {        mi[i]=query(map[i]-1);        build(map[i]);    }    sort(a+1,a+n+1,cmp2);    memset(f,0,sizeof(f));    for(i=1;i<=n;i++)    {        if(a[i].value==a[i-1].value)map[a[i].position]=map[a[i-1].position];        else map[a[i].position]=i;    }    for(i=n;i>0;i--)    {        ma[i]=query(map[i]-1);        build(map[i]);    }    for(i=1;i<=n;i++)ans+=mi[i]*ma[i];    printf("%lld",ans);}


阅读全文
0 0