题意:
给出一个数组,数组的每一个元素都是不一样的,求出对于3个数组下标 i, j, k such that i < j < k and ai > aj > ak where ax is the value at position x. 的个数
明显数组的值太大了
先离散化,然后就是简单的树状数组了
对于每一个i,只要统计i前面的数中比a[i]大的数的个数,和i后面的数中比a[i]小的数的个数即可
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <math.h> #define LL long long using namespace std; const int maxn = 1000000 + 10; struct Node { int id,init,chg; }; Node node[maxn]; int fir[maxn]; int sec[maxn]; int c[maxn]; bool cmp1(Node x,Node y) { return x.init<y.init; } bool cmp2(Node x,Node y) { return x.id<y.id; } inline int lb(int x) { return x & (-x); } void update(int x,int add) { while(x <= maxn){ c[x] += add; x += lb(x); } } int query(int x) { int ret = 0; while(x > 0){ ret += c[x]; x -= lb(x); } return ret; } LL solve(int n) { sort(node+1,node+n+1,cmp1); for(int i=1;i<=n;i++) node[i].chg = i; sort(node+1,node+n+1,cmp2); memset(c,0,sizeof c); for(int i=1;i<=n;i++){ fir[i] = i - 1 - query(node[i].chg - 1); update(node[i].chg,1); } memset(c,0,sizeof c); for(int i=n;i>0;i--){ sec[i] = query(node[i].chg - 1); update(node[i].chg,1); } LL ret = 0; for(int i=1;i<=n;i++) ret += (LL) fir[i] * sec[i]; return ret; } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&node[i].init); node[i].id = i; } //printf("%I64d ",solve(n)); cout<<solve(n)<<endl; return 0; }