您的位置:首页 > 其它

HDU 2492 (树状数组)

2016-04-16 02:24 316 查看
题目链接:点击打开链接

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

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

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: