这道题纠结了很长时间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;
}
加油!