题目大意:给一串数字,求在其中任意抽取一个三元组(x,y,z) 满足x<z<y 的总数
先求出 所有x < y < z和x < z < y,即x向右求逆序数
然后减去所有 x<y<z,即 sum - (y向左取正序数 * y向右取逆序数)
即为结果
#include<iostream>
#include<cstdio>
#include<cstring>
#define MOD 100000007
#define MAXX 100005
typedef long long ll;
int num[MAXX];
int c[MAXX];
int ans[MAXX];
using namespace std;
inline ll getSum(int i){
ll s=0;
while(i>0){
s+=c[i];
if(s>MOD) s%=MOD;
i-=i&(-i);
}
return s;
}
inline void Update(int i,int diff){
while(i<MAXX){
c[i]+=diff;
i+=i&(-i);
}
}
inline bool scan_d(int &num)
{
char in;bool IsN=false;
in=getchar();
if(in==EOF) return false;
while(in!='-'&&(in<'0'||in>'9')) in=getchar();
if(in=='-'){ IsN=true;num=0;}
else num=in-'0';
while(in=getchar(),in>='0'&&in<='9'){
num*=10,num+=in-'0';
}
if(IsN) num=-num;
return true;
}
int main(){
int n;
scanf("%d",&n);
int ca=1;
int m;
while(n--){
scanf("%d",&m);
for(int i=0;i<m;i++){
scan_d(num[i]);
ans[i]=getSum(num[i]);
Update(num[i],1);
}
memset(c,0,sizeof(c));
ll sum=0;
int k=0;
for(int i=m-1;i>=0;i--){
ll temp=k-getSum(num[i]);
sum=sum+(temp*(temp-1))/2;
sum=sum-temp*ans[i];
if(sum>MOD) sum%=MOD;
k++;
Update(num[i],1);
}
printf("Case #%d: %I64d\n",ca++,sum%MOD);
memset(c,0,sizeof(c));
memset(num,0,sizeof(num));
memset(ans,0,sizeof(ans));
}
return 0;
}