题目描述
Erwin最近对一种叫"thair"的东西巨感兴趣。。。
在含有n个整数的序列a1,a2......an中,
三个数被称作"thair"当且仅当i<j<k且ai<aj<ak
求一个序列中"thair"的个数。
输入输出格式
输入格式:
开始一个正整数n,
以后n个数a1~an。
输出格式:
"thair"的个数
输入输出样例
说明
对样例2的说明:
7个"thair"分别是
1 2 3 1 2 4 1 2 3 1 2 4 1 3 4 2 3 4 2 3 4 约定 30%的数据n<=100
60%的数据n<=2000
100%的数据n<=30000
大数据随机生成
0<=a[i]<=maxlongint
其实就是求逆序对,设ans1为之前比他小的数的个数,ans2为大的个数,显然ans+=ans1*ans2.
我们看到这数据规模,不能用桶,得离散化一下……然后常规操作。
AC代码如下:
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=30000+5;
struct p{
int id,num;
bool operator < (const p &aa) const{
return num<aa.num;}
}a[N];
int ans1[N],ans2[N],n,c[N],pos[N],now;
long long ans;
int sum(int x)
{
int res=0;
while(x>0) res+=c[x],x-=(x&-x);
return res;
}
void add(int x)
{
while(x<=n) c[x]++,x+=(x&-x);
return;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i].num),a[i].id=i;
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
pos[a[i].id]=((a[i].num!=a[i-1].num)||i==1)?i:pos[a[i-1].id];
for(int i=1;i<=n;i++)
now=pos[i],ans1[i]=sum(now-1),add(now);
fill(c+1,c+n+1,0);
for(int i=n;i>0;i--)
now=pos[i],ans2[i]=sum(n-now),add(n-now+1);
for(int i=1;i<=n;i++)
ans+=ans1[i]*ans2[i];
printf("%lld",ans);
return 0;
}