题目大意
给出一个长度为(n)的排列,求其中满足i<j<k且a[i]<a[k]且a[k]<a[j]的三元组(i,j,k)个数.
(nleq 100000)
思路
设满足i<j<k且a[i]<a[k]且a[k]<a[j]的三元组(i,j,k)个数为a.
满足i<j<k且a[i]<a[j]且a[j]<a[k]的三元组(i,j,k)个数为b.
满足i<j<k且a[i]<a[j]且a[i]<a[k]的三元组(i,j,k)个数为c.
显然有c=a+b
c,b都可以用树状数组轻松求出,相减就得到题目要求的a了。
Code
#include <cstdio>
#include <cstring>
#include <cstdlib>
typedef long long ll;
const int N = 2e5 + 7;
ll ans = 0, c[N], r[N];
int n, a[N];
void add(int po)
{ for (; po <= n; po += (po & (-po))) c[po]++; }
ll sum(int po)
{
ll ret = 0;
for (; po; po -= (po & (-po))) ret += c[po];
return ret;
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", a + i);
for (int i = n; i >= 1; i--)
{
r[i] = sum(n) - sum(a[i]);
ans += r[i] * (r[i] - 1) / 2, add(a[i]);
}
memset(c, 0, sizeof(c));
for (int i = 1; i <= n; i++)
ans -= sum(a[i] - 1) * r[i], add(a[i]);
printf("%lld
", ans);
return 0;
}