题意:给出一个序列,求满足1<=a<b<=n,1<=c<d<=n,num[a]<num[b],num[c]>num[d],四元组a,b,c,d的个数。
设l[i]代表左边小于num[i]的个数,l1[i]代表左边大于num[i]的个数,r[i]代表右边小于num[i]的个数,r1[i]代表右边大于num[i]的个数。
ans=ab二元组的个数*cd二元组的个数-ac相等时三元组的个数-bc相等时三元组的个数-ad相等时三元组的个数-bd相等时三元组的个数
ab二元组的个数=l[i]的和,cd二元组的个数=r[i]的和,ac相等时三元组的个数=r[i]*r1[i]的和,bc相等时三元组的个数=l[i]*r[i]的和,ad相等时三元组的个数=l1[i]*r[i]的和,cd相等时三元组的个数=l[i]*l1[i]的和
然后就完美解决了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define Max(a,b) a>b?a:b
int n,id;
const int maxn=5e4+10;
int c[maxn];
pair<int,int> q[maxn];
bool cmp(pair<int,int> x,pair<int,int> y)
{
if(x.first!=y.first)
return x.first<y.first;
return x.second<y.second;
}
bool cmp1(pair<int,int> x,pair<int,int> y)
{
return x.second<y.second;
}
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int v)
{
while(x<=id+5)
{
c[x]+=v;
x+=lowbit(x);
}
}
int sum(int x)
{
int s=0;
while(x)
{
s+=c[x];
x-=lowbit(x);
}
return s;
}
int l[maxn],r[maxn],l1[maxn],r1[maxn];
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
{
c[i]=0;
q[i].second=i;
scanf("%d",&q[i].first);
}
sort(q+1,q+n+1,cmp);
int tmp=q[1].first;
id=1;q[1].first=1;
for(int i=2;i<=n;i++)
{
if(q[i].first>tmp)
{
tmp=q[i].first;
q[i].first=++id;
}
else
q[i].first=id;
}
sort(q+1,q+n+1,cmp1);
for(int i=1;i<=n;i++)
{
add(q[i].first,1);
l[i]=sum(q[i].first-1);
l1[i]=sum(id)-sum(q[i].first);
}
for(int i=0;i<=id;i++)
c[i]=0;
for(int i=n;i>=1;i--)//因为有重复,要分开来求
{
add(q[i].first,1);
r[i]=sum(q[i].first-1);
r1[i]=sum(id)-sum(q[i].first);
}
long long ans1,ans2,ans3;
ans1=ans2=ans3=0;
for(int i=1;i<=n;i++)
{
ans3+=1ll*l[i]*r[i];
ans3+=1ll*l1[i]*r1[i];
ans3+=1ll*l[i]*l1[i];
ans3+=1ll*r[i]*r1[i];
ans1+=l[i],ans2+=r[i];
}
cout<<ans1*ans2-ans3<<endl;
}
}