题意:
给一个数列A,统计有多少个四元组(a, b, c, d)满足Aa < Ab, Ac > Ad.(a != b != c != d)且a<b,c<d.
思路:
如果没有(a != b != c != d)的条件,那么问题其实就是统计A序列中逆序对和正序对个数然后相乘及是答案。
但是,现在这个条件存在表明多统计了(a == c || a == d || b == c || b == d)的情况,这几个情况限制下其它两个值是必定不会相等的,所以我们把ans减掉这些情况就好了。
我们需要预处理出lmi[i], lmx[i], rmi[i], rmx[i].
lmi[i]:[1, i-1]之间值比ai小的个数
lmx[i]:[1, i-1]之间值比ai大的个数
rmi[i]:[i+1, n]之间值比ai小的个数
rmx[i]:[i+1, n]之间值比ai大的个数
a == c时: ans -= rmx[i]*rmi[i].
a == d时: ans -= rmx[i]*lmx[i].
b == c时: ans -= lmi[i]*rmi[i].
b == d时: ans -= lmi[i]*lmx[i].
代码:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 5e5+5;
int n, cnt;
int a[maxn], b[maxn];
int c[maxn];
int lmx[maxn], lmi[maxn], rmx[maxn], rmi[maxn];
int lowbit(int x){return x&(-x);}
void update(int k)
{
while(k <= cnt)
{
++c[k];
k += lowbit(k);
}
}
int query(int k)
{
int ans = 0;
while(k)
{
ans += c[k];
k -= lowbit(k);
}
return ans;
}
int main()
{
int cnt1, cnt2;
while(~scanf("%d", &n))
{
for(int i = 1; i <= n; ++i) scanf("%d", &a[i]), b[i] = a[i];
sort(b+1, b+n+1);
cnt = unique(b+1, b+n+1)-(b+1);
for(int i = 1; i <= n; ++i)
a[i] = lower_bound(b+1, b+cnt+1, a[i])-b;
cnt1 = 0, cnt2 = 0;
memset(c, 0, sizeof c);
for(int i = 1; i <= n; ++i)
{
lmi[i] = query(a[i]-1);
lmx[i] = query(cnt)-query(a[i]);
cnt1 += lmx[i];
cnt2 += lmi[i];
update(a[i]);
}
memset(c, 0, sizeof c);
for(int i = n; i >= 1; --i)
{
rmi[i] = query(a[i]-1);
rmx[i] = query(cnt)-query(a[i]);
update(a[i]);
}
LL ans = 1ll*cnt1*cnt2;
for(int i = 1; i <= n; ++i)
{
ans -= 1ll*rmx[i]*rmi[i];
ans -= 1ll*rmx[i]*lmx[i];
ans -= 1ll*lmi[i]*rmi[i];
ans -= 1ll*lmi[i]*lmx[i];
}
printf("%lld\n", ans);
}
return 0;
}
继续加油~