CH4201 樓蘭圖騰 樹狀數組

題目鏈接

http://noi-test.zzstep.com/contest/0x40%E3%80%8C%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E8%BF%9B%E9%98%B6%E3%80%8D%E4%BE%8B%E9%A2%98/4201%20%E6%A5%BC%E5%85%B0%E5%9B%BE%E8%85%BE

分析

給出的縱座標是按照橫座標升序給出的,對於所有縱座標,在其左側較小的數的個數乘上在其右側較小的數的個數就是^的個數;v同理。

AC代碼

#include <cstdio>
#include <cstring>

inline int read() {
	int num = 0;
	char c = getchar();
	while (c < '0' || c > '9') c = getchar();
	while (c >= '0' && c <= '9')
		num = num * 10 + c - '0', c = getchar();
	return num;
}

const int maxn = 2e5 + 5;

int n, a[maxn], b[maxn], c[maxn], bit[maxn];

inline int ask(int x) {
	int ret = 0;
	while (x) ret += bit[x], x -= x & (-x);
	return ret;
}

inline void add(int x, int d) {
	while (x <= n) bit[x] += d, x += x & (-x);
}

int main() {
	n = read();
	for (int i = 1; i <= n; ++i)
		a[i] = read(), b[i] = ask(a[i] - 1), add(a[i], 1);
	memset(bit, 0, sizeof(bit));
	for (int i = n; i; --i) c[i] = ask(a[i] - 1), add(a[i], 1);
	long long cnt1 = 0, cnt2 = 0;
	for (int i = 1; i <= n; ++i)
		cnt1 += (i - 1ll - b[i]) * (n - i - c[i]), cnt2 += 1ll * b[i] * c[i];
	printf("%lld %lld", cnt1, cnt2);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章