HDU 2492 (树状数组)

题目链接:点击打开链接

题意:求出数列递增或者递减的三元组个数。

用树状数组维护每个数左边和右边有几个数比自己大/小即可。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
#define maxn 21111

struct node {
	int num;
	int pos;
} p[maxn];
bool cmp1 (const node &a, const node &b) {
	return a.num < b.num;
}
bool cmp2 (const node &a, const node &b) {
	return a.num > b.num;
}
int l[maxn], r[maxn];//左边比他小的 右边比他小的
int ll[maxn], rr[maxn];//左边比他大的 右边比他大的
int c[maxn], n;

int lowbit (int x) {
	return x&(-x);
}

void add (int pos) {
	for (int i = pos; i <= n; i += lowbit (i)) {
		c[i]++;
	}
}

int sum (int pos) {
	int ans = 0;
	for (int i = pos; i >= 1; i -= lowbit (i)) {
		ans += c[i];
	}
	return ans;
}

int main () {
	int t;
	scanf ("%d", &t);
	while (t--) {
		scanf ("%d", &n);
		for (int i = 1; i <= n; i++) {
			scanf ("%d", &p[i].num);
			p[i].pos = i;
		}
		sort (p+1, p+1+n, cmp1);
		memset (c, 0, sizeof c);
		for (int i = 1; i <= n; i++) {
			l[p[i].pos] = sum (p[i].pos);
			r[p[i].pos] = sum (n)-l[p[i].pos];
			add (p[i].pos);
		}
		sort (p+1, p+1+n, cmp2);
		memset (c, 0, sizeof c);
		for (int i = 1; i <= n; i++) {
			ll[p[i].pos] = sum (p[i].pos);
			rr[p[i].pos] = sum (n)-ll[p[i].pos];
			add (p[i].pos);
		}
		long long ans = 0;
		for (int i = 1; i <= n; i++) {
			ans += 1LL*l[i]*rr[i] + 1LL*r[i]*ll[i];
		}
		cout << ans << endl;
	}
	return 0;
}


你可能感兴趣的:(HDU 2492 (树状数组))