树状数组的应用 Mega Inversions

 Mega Inversions

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 84  Solved: 17
[Submit][Status][Web Board]

Description

The n^2 upper bound for any sorting algorithm is easy to obtain: just take two elements that are misplaced with respect to each other and swap them. Conrad conceived an algorithm that proceeds by taking not two, but three misplaced elements. That is, take three elements ai > aj > ak with i < j < k and place them in order ak; aj ; ai. Now if for the original algorithm the steps are bounded by the maximum number of inversions n(n-1)/2, Conrad is at his wits' end as to the upper bound for such triples in a given sequence. He asks you to write a program that counts the number of such triples.

Input

The fi rst line of the input is the length of the sequence, 1 <= n <= 10^5.
The next line contains the integer sequence a1; a2..an.
You can assume that all ai belongs [1; n].

Output

Output the number of inverted triples.

Sample Input

4
3 3 2  1

Sample Output

2
题意很简单就是求:满足 ai> aj> ak (i<j<k) 的个数 ,和2008年北京赛区的ping pong很像 ,只不过那题没有重复元素,这题就有,需要离散化
View Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
#define lowbit(x) x&(-x)

const int maxn=5000100;

int n,a[maxn],b[maxn],c[maxn],len;
int ans1[maxn],ans2[maxn];

void insert(int pos)
{
for(int i=pos;i<len;i+=lowbit(i))
a[i]++;
}
int query(int pos)
{
int sum=0;
for(int i=pos;i>=1;i-=lowbit(i)) sum+=a[i];
return sum;
}
int bin(int r,int key)
{
int l,m;
l=1,m=1;
while(l<=r)
{
m=(l+r)>>1;
if(c[m]==key) return m;
else if(c[m]<key) l=m+1;
else r=m-1;
}
}
bool mark[maxn];
int main()
{
int n;
while(cin>>n)
{
memset(a,0,sizeof(a));
memset(mark,0,sizeof(mark));
for(int i=1;i<=n;i++)
cin>>b[i],c[i]=b[i];
sort(c+1,c+1+n);
len=1;
for(int i=1;i<=n;i++) if(c[i]!=c[i-1]) c[len++]=c[i];
for(int i=1;i<=n;i++)
{
int pos=bin(len-1,b[i]);
ans1[i]=query(pos);
insert(pos);
mark[pos]=1;
}
memset(mark,0,sizeof(mark));
memset(a,0,sizeof(a));
for(int i=n;i>=1;i--)
{
int pos=bin(len-1,b[i]);
if(mark[pos])
ans2[i]=query(pos-1);
else ans2[i]=query(pos);
insert(pos);
mark[pos]=1;
}
long long sum=0;
for(int i=1;i<=n;i++)
{
sum+=(long long)(i-1-ans1[i])*ans2[i];
}
cout<<sum<<endl;
}
return 0;
}


 

posted on 2012-04-07 13:51  Goal  阅读(416)  评论(0编辑  收藏  举报

导航