/*
比赛的时候没有写出来,赛后请教大牛后写的
可以先求出(xyz,xzy)的总数量
只需出去x后面多少个比它大的个数n,C(n,2)就是了
然后求出xyz的个数,
对于a,求出比a小的个数low[a],比a大的个数high[a],low[a]*high[a]就是答案
可以借助树状数组求上述个数
*/
#include <cstdio>
#include <iostream>
#include <memory.h>
using namespace std;
const int MAX=100100;
const __int64 mod=100000007;
__int64 C[MAX];
__int64 low[MAX];//low[a],在a前面比a小的个数
__int64 high[MAX];//high[a],在a后面比a大的个数
int Case;
int n;
int data[MAX];
int low_bit(int x) {
return x&(-x);
}
void add_up(int x) {
while(x<=n) {
C[x]+=1;
x+=low_bit(x);
}
}
__int64 sum(int x) {
__int64 s=0;
while(x) {
s+=C[x];
x-=low_bit(x);
}
return s;
}
void solve() {
Case++;
__int64 a=0, b=0;
scanf("%d", &n);
memset(C, 0, sizeof(C));
for(int i=1;i<=n;i++) {
scanf("%d", &data[i]);
low[i]=sum(data[i]);
high[i]=n-data[i]-i+1+low[i];
add_up(data[i]);
}
for(int i=1;i<=n;i++) {
b=((b+low[i]*high[i])%mod+mod)%mod;
}
for(int i=1;i<=n;i++) {
a=((a+high[i]*(high[i]-1)/2)%mod+mod)%mod;
}
printf("Case #%d: ", Case);
printf("%I64d\n", (a-b+mod)%mod);
}
int main () {
int T;
scanf("%d", &T);
while(T--)
solve();
return 0;
}
hdu 4000 Fruit Ninja 树状数组+统计
最新推荐文章于 2020-06-09 19:27:52 发布