您的位置:首页 > 其它

hud 2838 Cow Sorting 树状数组求逆序数

2016-09-25 10:07 316 查看
这道题纠结了很长时间0.0,今天早起重写了一发结果就a 了,Orz

主要原因还是算逆序数个数的时候没开long long,我还以为算sum的和的时候开long long 就好了,没想到光光是逆序数的个数就到达long long的级别了,下次还是要小心啊!

重写一次果然代码看起来清爽不少。


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL __int64

struct nu {
int x,t;
} num[100005];
LL n,sum[100005],cnt[100005],ans;

bool tmp(nu a,nu b) {
return a.x > b.x;
}

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

void getsum(int t,int x) { //一个算逆序数的个数,另外一个算逆序数的和,就算是个数也要开long long
LL cc = 0;
while(t) {
ans += sum[t];
cc += cnt[t];
t -= lowbit(t);
}
ans += cc*x;
}

void add(int t,int d,int x) { //两个一起加简洁点
while(t <= n) {
sum[t] += x;
cnt[t] += d;
t += lowbit(t);
}
}

int main() {
scanf("%I64d",&n);
for(int i = 1;i <= n;i++) {
scanf("%d",&num[i].x);
num[i].t = i;
}
sort(num+1,num+1+n,tmp); //这种先排序再add进去算逆序数的方法还是不错的,不用考虑数据给的太大数组存不下
memset(sum,0,sizeof(sum));
memset(cnt,0,sizeof(cnt));
ans = 0;
for(int i = 1;i <= n;i++) {
add(num[i].t,1,num[i].x);
getsum(num[i].t-1,num[i].x);
}
printf("%I64d\n",ans);
return 0;
}加油!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  树状数组 逆序数