您的位置:首页 > 其它

cf 61 E. Enemy is weak 离散化+树状数组

2015-11-28 14:34 676 查看
题意:

给出一个数组,数组的每一个元素都是不一样的,求出对于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\n",solve(n));
cout<<solve(n)<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: