Time Limit: 3000/1000MS (Java/Others)
Memory Limit: 65535/65536KB (Java/Others)
陆伯言军陷八卦阵之中,分明只是一条直路,却怎的也走不到尽头。阵中尽是石堆,以某一石堆为参考,无论向走还是向右,总是会回到出发的石堆,最后幸得一黄姓老翁带路才得脱出。
陆伯言逃离八卦阵后,来到山顶观察此阵,记从左往右第i堆石堆的高度为Ai,发现任何两堆较矮的石堆都能和它们之间的一座较高的石堆形成”八卦锁”,将其中之人牢牢锁住,无从逃脱。
根据石堆的情况,陆伯言大致计算了“八卦锁”的数量(即
Ai<Aj>Ak,i<j<k
A
i
<
A
j
>
A
k
,
i
<
j
<
k
的组合数),不禁心中一惊,对孔明惊为天人,遂放弃追击,收兵回吴。
“有劳岳父了。” “为何将其放走?” “…一表人才,何必浪费于此。”
Input
第一行一个整数n,表示石堆堆数。接下来一行,n个整数,第i个数表示从左到右第i堆石堆的高度Ai。( 1≤n≤50000,1≤Ai≤32768 1 ≤ n ≤ 50000 , 1 ≤ A i ≤ 32768 )
Output
一个整数,“八阵锁”的数目。
Sample Input
5
1 2 3 4 1
Sample Output
6
Source
2014 UESTC Training for Data Structures
* 题解:*
正反各扫一次,对于每一个
a[i]
a
[
i
]
,用树状数组统计
a[j]<a[i]
a
[
j
]
<
a
[
i
]
和
a[k]<a[i](i<j<k)
a
[
k
]
<
a
[
i
]
(
i
<
j
<
k
)
的数量
ca[i]
c
a
[
i
]
和
ta[i]
t
a
[
i
]
。然后
ans=Σ(ca[i]∗ta[i])
a
n
s
=
Σ
(
c
a
[
i
]
∗
t
a
[
i
]
)
#include<bits/stdc++.h>
#define LiangJiaJun main
#define ll long long
using namespace std;
inline int lowbit(int x){return x&(-x);}
int n,a[50004];
ll ca[50004],ta[50004],tr[50004];
void add(int x,int val){
for(int i=x;i<=40000;i+=lowbit(i))tr[i]+=val;
}
ll query(int x){
ll res=0;
for(int i=x;i;i-=lowbit(i))res+=tr[i];
return res;
}
ll ret=0;
int LiangJiaJun(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
ca[i]=query(a[i]-1);
add(a[i],1);
}
memset(tr,0,sizeof(tr));
for(int i=n;i>=1;i--){
ta[i]=query(a[i]-1);
add(a[i],1);
}
for(int i=1;i<=n;i++)ret+=ta[i]*ca[i];
printf("%lld\n",ret);
return 0;
}