题目:http://acm.hdu.edu.cn/showproblem.php?pid=5792
题意:给你一串数组A,要求
a≠b≠c≠d,1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ad
a≠b≠c≠d,Aa<Ab,Ac>Ad
题解:先只考虑 Aa<Ab,Ac>Ad 的情况,然后一个一个排除掉a==c a==d b==c b==d 这四种情况
要建立4个数组,left_low,left_high,right_high,right_low,如意,已left_low,为例,left_low[i]就是i左边(按输入的顺序)比i对应的数值小的数字有多少个,用树状数组来查,压缩到o(nlogn),建立完之后就通过如代码上的关系来进行计算(可自己推断出)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
typedef struct
{
int value;
int w;
}Test;
Test test[50005];
int value[50005];
int c[50005];
int left_high[50005];
int left_low[50005];
int right_high[50005];
int right_low[50005];
bool compare(Test a,Test b)
{
return a.value>b.value;
}
int lowerbit(int x)
{
return x&(-x);
}
int sum(int x)
{
int sum=0;
for(int i=x;i>0;i-=lowerbit(i))
{
sum+=c[i];
}
return sum;
}
void add(int x,int val,int n)
{
for(int i=x;i<=n;i+=lowerbit(i))
{
c[i]+=val;
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++) {scanf("%d",&test[i].value);test[i].w=i;}
sort(test+1,test+n+1,compare);
for(int i=1;i<=n;i++){value[test[i].w]=i;if(i+1<=n&&test[i].value==test[i+1].value){
for(int j=i+1;j<=n;j++)
{
value[test[j].w]=i;
if(test[j].value!=test[j+1].value){i=j;break;}
}
}}
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
{
left_high[i]=sum(value[i]-1);
left_low[i]=i-1-sum(value[i]);
add(value[i],1,n);
}
memset(c,0,sizeof(c));
for(int i=n;i>0;i--)
{
right_high[i]=sum(value[i]-1);
right_low[i]=sum(n)-sum(value[i]);
add(value[i],1,n);
}
long long ans1=0;
long long ans2=0;
for(int i=1;i<=n;i++)
{
ans1+=right_low[i];
ans2+=right_high[i];
}
ans1*=ans2;
ans2=0;
for(int i=1;i<=n;i++)
{
ans2+=right_high[i]*right_low[i];
ans2+=left_high[i]*right_high[i];
ans2+=left_low[i]*right_low[i];
ans2+=left_high[i]*left_low[i];
}
ans1-=ans2;
printf("%lld\n",ans1);
}
return 0;
}