题意:在一个数组a[]中找出符合i < j < k && a[i] < a[k] < a[j] 的组数;
思路: 可以从反面进行求出:a[i] < a[k] < a[j] 的情况等价于 a[i] < a[j] && a[i] < a[k] 减去 a[i] < a[j] < a[k]的情况;
废话不多说,直接上代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 10;
#define mod 100000007
ll a[maxn];
ll tree[maxn];
ll b[maxn];
ll c[maxn];
ll n;
ll inline lowbit(ll x)
{
return x & (-x);
}
ll get(ll x)
{
ll ans = 0;
for(ll i = x ; i >0 ; i -= lowbit(i))
{
ans += tree[i];
}
return ans;
}
ll update(ll x,ll val)
{
for(ll i = x; i < maxn ; i += lowbit(i))
tree[i] += val;
}
int main()
{
int Tcase;
scanf("%d",&Tcase);
for(int ii = 1; ii <= Tcase ; ii ++)
{
scanf("%I64d",&n);
memset(tree,0,sizeof(tree));
for(ll i = 1; i <= n ; i ++)
scanf("%I64d",&a[i]);
for(int i = 1; i <= n ; i ++)//记录的前面比这个数小的个数
{
b[i] = get(a[i]);
update(a[i],1);
}
memset(tree,0,sizeof(tree));
for(int i = n ; i>= 1; i --)//记录后面的数比这个数小的个数
{
c[i] = get(a[i]);
update(a[i],1);
}
//情况是a<b && a< c 减去a < b < c的情况,就是 a < c < b
ll ans = 0;
for(int i = 1; i <= n - 2; i ++)//第一种情况
{
ans = (ans + ( (n - i - c[i]) *(n - i -1 - c[i] ) / 2)%mod ) % mod;
}
ll temp = 0;
for(int i = 2; i <= n - 1;i ++)//第二种情况
{
temp = (temp + ((b[i] * (n - i - c[i])))%mod )%mod;
}
ans = (ans - temp + mod)%mod;
cout <<"Case #"<< ii <<": "<< ans << endl;
}
return 0;
}