很简单的树状数组求逆序对,然后两两匹配的方案数。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#define gc getchar()
#define ll long long
using namespace std;
const int N=2e5+5;
inline void qr(int &x)
{
    x=0;char c=gc;
    while(c<'0'||c>'9')c=gc;
    while(c>='0'&&c<='9'){x=x*10+(c^48);c=gc;}
}
void qw(ll x)
{
    if(x/10)qw(x/10);
    putchar(x%10+48);
}
int n,c[N];
inline void add(int x){for(;x<=n;x+=x&-x)++c[x];}
inline int ask(int x){int ans=0;for(;x;x-=x&-x)ans+=c[x];return ans;}
int l1[N],a[N],l2[N],r1[N],r2[N];
int main()
{
    qr(n);
    for(int i=1;i<=n;i++)qr(a[i]);
    for(int i=1;i<=n;i++){l2[i]=ask(a[i]);l1[i]=i-1-l2[i];add(a[i]);}memset(c,0,sizeof(c));
    ll ans=0;
    for(int i=n;i;i--){r2[i]=ask(a[i]);r1[i]=n-i-r2[i];add(a[i]);}
    for(int i=1;i<=n;i++)ans+=1ll*r1[i]*l1[i];qw(ans);putchar(' ');
    ans=0;
    for(int i=1;i<=n;i++)ans+=1ll*r2[i]*l2[i];qw(ans);puts("");
    return 0;
}