BIT LA 4329 Ping pong

题目传送门

题意:训练指南P197

分析:枚举裁判的位置,用树状数组来得知前面比它小的和大的以及后面比它小的和大的,然后O (n)累加小 * 大 + 大 * 小 就可以了

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N = 1e5 + 5;
const int M = 2e4 + 5;
struct BIT	{
	int c[N], sz;
	void init(int n)	{
		memset (c, 0, sizeof (c));
		sz = n;
	}
	void updata(int i, int x)	{
		while (i <= sz)	{
			c[i] += x;	i += i & -i;
		}
	}
	int query(int i)	{
		int ret = 0;
		while (i)	{
			ret += c[i];	i -= i & -i;
		}
		return ret;
	}
}bit;
int a[M], small[M][2], large[M][2];

int main(void)	{
	int T;	scanf ("%d", &T);
	while (T--)	{
		bit.init (100000);
		int n;	scanf ("%d", &n);
		for (int i=1; i<=n; ++i)	{
			scanf ("%d", &a[i]);
			small[i][0] = bit.query (a[i] - 1);
			large[i][0] = i - 1 - small[i][0];
			bit.updata (a[i], 1);
		}
		for (int i=1; i<=n; ++i)	{
			small[i][1] = bit.query (a[i] - 1) - small[i][0];
			large[i][1] = n - i - small[i][1];
		}
		ll ans = 0;
		for (int i=1; i<=n; ++i)	{
			ans += 1ll * small[i][0] * large[i][1];
			ans += 1ll * large[i][0] * small[i][1];
		}
		printf ("%lld
", ans);
	}

	return 0;
}

  

编译人生,运行世界!
原文地址:https://www.cnblogs.com/Running-Time/p/5027390.html