给一列互不相同的数,统计第i个位置(2 < i < n-1)左侧比他值小的与右侧比他大的乘积+左侧比他大的与右侧比他小的乘积 的和。看懂题意后实际就是个bit的应用...不过需要稍微预处理下,用a[i],c[i]两个数组表示,更新到第i个数时,能力值小于等于当前位置能力值的人数和能力值大于当前位置能力值的人数。循环一边处理完后,从2到n-i枚举一边,把左边小的和右边大的乘起来,左边大的右边小的乘起来,求个和就像你给了。
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <memory.h> using namespace std; typedef __int64 ll; const int maxn=200010; int tr[maxn]; int n,m,p,q,k,mxn; struct BIT { int lowbit(int x) { return x&-x; } void add(int x,int c=1) { for (int i=x; i<=mxn; i+=lowbit(i)) { tr[i]+=c; } } ll sum(int x) { ll res=0; for (int i=x; i>0; i-=lowbit(i)) res+=tr[i]; return res; } }bit; int tt; ll a[maxn],c[maxn]; int dt[maxn]; int main() { // freopen("in.txt","r",stdin); scanf("%d",&tt); while(tt--) { memset(tr,0,sizeof tr); scanf("%d",&n); mxn=0; for (int i=1; i<=n; i++) { scanf("%d",&dt[i]); mxn=max(mxn,dt[i]); } for (int i=1; i<=n; i++) { m=dt[i]; bit.add(m,1); a[i]=bit.sum(m); c[i]=ll(i-a[i]); } // for (int i=1; i<=n; i++) // cout<<a[i]<<" "<<c[i]<<endl; ll ans=0; ll x1,x2,y1,y2; for (int i=2; i<n; i++) { x1=a[i]-1; x2=bit.sum(dt[i])-a[i]; y1=(i-a[i]); y2=n-bit.sum(dt[i])-y1; // cout<<x1<<" "<<y2<<" | "<<x1<<" "<<x2<<endl; ans+=x1*y2; ans+=y1*x2; } printf("%I64d\n",ans); } return 0; }