思路:树状数组 + Y轴前缀和
链接:AcWing_241
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
int tr[N];
int arr[N];
ll g[N],l[N],great[N],les[N];
int n;
int lowbit(int x)
{
return x&-x;
}
void add(int x)
{
for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=1;
return ;
}
ll query(int x)
{
ll res=0;
for(int i=x;i>0;i-=lowbit(i)) res+=tr[i];
return res;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&arr[i]);
g[i]=query(n)-query(arr[i]);
l[i]=query(arr[i]);//因为是排列数所以在arr[i]插入前不会有arr[i],也可以l[i]=query(arr[i]-1)
add(arr[i]);
}
memset(tr,0,sizeof tr);
for(int i=n;i>=1;i--)
{
great[i]=query(n)-query(arr[i]);
les[i]=query(arr[i]);
add(arr[i]);
}
ll res=0,ans=0;
for(int i=1;i<=n;i++)
{
res=res+g[i]*great[i];
ans=ans+l[i]*les[i];
}
printf("%lld %lld\n",res,ans);
return 0;
}