正题
题目大意
一个序列SSS,求有多少个互不相同的4元组(a,b,c,d)(a,b,c,d)(a,b,c,d)使得a<b且Sa<Sba<b且S_a<S_ba<b且Sa<Sb
c<b且Sc>Sdc<b且S_c>S_dc<b且Sc>Sd
解题思路
若可以重复其实答案就是逆序对个数乘上正序对个数。
然后我们考虑将重复的去掉
这里定义up1,down1up_1,down_1up1,down1为左边大于/小于该数的个数,up2,down2up2,down2up2,down2为右边大于/小于该数的个数。
若a=ca=ca=c,那么有Sd<Sa=c<SbS_d<S_{a=c}<S_bSd<Sa=c<Sb,且(a=c)<b,d(a=c)< b,d(a=c)<b,d,为up2∗down2up2*down2up2∗down2
若a=da=da=d,那么有Sc>Sa=d<SbS_c>S_{a=d}<S_bSc>Sa=d<Sb,且c<(a=d)<bc<(a=d)<bc<(a=d)<b,为up1∗up2up1*up2up1∗up2
若b=cb=cb=c,那么有Sa<Sb=c>SdS_a<S_{b=c}>S_dSa<Sb=c>Sd,且a<(b=d)<da<(b=d)<da<(b=d)<d,为down1∗down2down1*down2down1∗down2
若b=db=db=d,那么有Sa<Sb=d<ScS_a<S_{b=d}<S_cSa<Sb=d<Sc,且a,c<(b=d)a,c<(b=d)a,c<(b=d),为up1∗down1up1*down1up1∗down1
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lowbit(x) (x&-x)
#define ll long long
using namespace std;
const ll N=1e5+100;
ll n,a[N],c[N],s1,s2,z,m;
struct Tree_array{ll t[N];void Clear(){memset(t,0,sizeof(t));}void Change(ll x,ll z){while(x<=m){t[x]+=z;x+=lowbit(x);}}ll Ask(ll x){ll ans=0;while(x){ans+=t[x];x-=lowbit(x);} return ans;}
}T1,T2;
int main()
{freopen("a.in","r",stdin);freopen("a.out","w",stdout);scanf("%lld",&n);for(ll i=1;i<=n;i++)scanf("%lld",&a[i]),c[i]=a[i];sort(c+1,c+1+n);m=unique(c+1,c+1+n)-c-1;for(ll i=1;i<=n;i++){a[i]=lower_bound(c+1,c+1+m,a[i])-c;T2.Change(a[i],1);}for(ll i=1;i<=n;i++){ll down1=T1.Ask(a[i]-1),up1=T1.Ask(m)-T1.Ask(a[i]);ll down2=T2.Ask(a[i]-1),up2=T2.Ask(m)-T2.Ask(a[i]);s1+=down1;s2+=down2;z+=up2*down2+up1*up2+down1*down2+up1*down1;T1.Change(a[i],1);T2.Change(a[i],-1);}printf("%lld",s1*s2-z);
}