比赛 |
20120709 |
评测结果 |
AAAAAAAAAA |
题目名称 |
数列 |
最终得分 |
100 |
用户昵称 |
ZhouHang |
运行时间 |
0.133 s |
代码语言 |
C++ |
内存使用 |
2.12 MiB |
提交时间 |
2012-07-09 11:10:45 |
显示代码纯文本
/*Task : b
*Data : 2.19
*Sol : 线段树
*Auth : Zhou Hang
*/
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MaxNum=40000;
const int MaxN=51000;
const int oo=1000000000;
int a[4*MaxNum+100][2];
int m,n,ans,i,x,y,ch;
int l[MaxN],r[MaxN],h[MaxN];
void updata(int l,int r,int root)
{
if ((y<l)||(x>r)) return;
if ((x<=l)&&(y>=r))
{
a[root][0]++; a[root][1]++;
return;
}
int mid=(l+r)/2;
//必须是临时变量,避免递归时改变
//left child
a[root*2][0]+=a[root][1];
a[root*2][1]+=a[root][1];
//right child
a[root*2+1][0]+=a[root][1];
a[root*2+1][1]+=a[root][1];
//itself
a[root][1]=0;
updata(l,mid,root*2);
updata(mid+1,r,root*2+1);
//change Sum
a[root][0]=a[root*2][0]+a[root*2+1][0];
}
int find(int l,int r,int root)
{
if ((y<l)||(x>r)) return 0;
if ((x<=l)&&(y>=r)) return a[root][0];
int mid=(l+r)/2;
//left child
a[root*2][0]+=a[root][1];
a[root*2][1]+=a[root][1];
//right child
a[root*2+1][0]+=a[root][1];
a[root*2+1][1]+=a[root][1];
//itself
a[root][1]=0;
int m1=find(l,mid,root*2);
int m2=find(mid+1,r,root*2+1);
return m1+m2;
}
int main()
{
freopen("queueb.in","r",stdin);
freopen("queueb.out","w",stdout);
scanf("%d",&n);
int maxh = -1;
for (int i=1; i<=n; i++) {
scanf("%d",&h[i]);
if (h[i]>maxh) maxh = h[i];
}
for (int i=1; i<=n; i++) {
x = y = h[i];
updata(0,maxh,1);
x = 0; y = h[i]-1;
l[i] = find(0,maxh,1);
}
memset(a,0,sizeof(a));
for (int i=n; i>=1; i--) {
x = y = h[i];
updata(0,maxh,1);
x = 0; y = h[i]-1;
r[i] = find(0,maxh,1);
}
long long ans = 0;
for (int i=1; i<=n; i++)
ans += (long long)l[i]*r[i];
cout<<ans<<endl;
fclose(stdin); fclose(stdout);
}