HDU 2492 (树状数组)

来源:互联网 发布:xfiles theme知乎 编辑:程序博客网 时间:2024/06/01 22:12

题目链接:点击打开链接

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

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

#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <iostream>using namespace std;#define maxn 21111struct 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;}


0 0
原创粉丝点击