poj 1990 树状数组

主要参考:http://1.congzhao.sinaapp.com/?p=1014  非常感谢。让我学习了

  非常累,今天没什么状态啊。。。。好了,今天就到这吧。 要换编译器了。VC++不合适做OJ上面的题

#include <iostream>
#include <algorithm>
#include <fstream>

using namespace std;

#define N 20100
int n; //牛的个数
struct Node{
long long v,x;
bool operator<(Node a){
return v<a.v;
}
}nn[N];

long long arx[N],arn[N]; //arx树状数组记录位置和,arn树状数组记录数量和
inline int lowbit(int x){ //内联
return x&(-x);
}

void addx(int i,long long v){
for(;i<N ;arx[i]+=v ,i+=lowbit(i));
}

long long sumx(int i){
long long sum=0;
for(;i>0;sum+=arx[i] ,i-=lowbit(i));
return sum;
}

void addn(int i,long long n=1){
for(;i<N ;arn[i]+=n ,i+=lowbit(i));
}

long long sumn(int i){
int sum=0;
for(;i>0;sum+=arn[i] ,i-=lowbit(i));
return sum;
}

int main(){
//freopen("acm.txt","r",stdin);
scanf("%d",&n);
for(int i=0 ;i<n ;i++){
scanf("%d%d",&nn[i].v,&nn[i].x);
}
sort(nn,nn+n);
long long ans=0;
for(int i=0 ;i<n ;i++){
long long up=(sumx(N-1)-sumx(nn[i].x))-nn[i].x*(sumn(N-1)-sumn(nn[i].x)); //后面的距离和
long long down=sumn(nn[i].x-1)*nn[i].x-sumx(nn[i].x-1); //注意取值。。
ans+=nn[i].v*(up+down); //前后的牛让第i个牛听见的volumes
addx(nn[i].x,nn[i].x);
addn(nn[i].x);
}
printf("%lld\n",ans);
return 0;
}

 

你可能感兴趣的:(树状数组)