题目: http://acm.pku.edu.cn/JudgeOnline/problem?id=1990
先按V关键字从小到大排序,然后分别统计当前i 比Xi小的坐标的个数,和比Xi小的 个数和 比XI大的个数。
然后计算即可。
#include <cmath>
#include <ctime>
#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
#include <stack>
#include <deque>
using namespace std;
typedef long long LL;
#define EPS 10e-9
#define INF 0x3f3f3f3f
#define REP(i,n) for(int i=0; i<(n); i++)
const int maxn = 20000+100;
struct node{
int x,v;
bool operator <(const node &b) const {
return v<b.v;
}
}cow[maxn];
int cnt_dit[maxn],cnt_num[maxn];
int lowbit(int x){ return x&-x;}
int sum(int *a,int x){
int ret=0;
while(x>0){
ret+=a[x]; x-=lowbit(x);
}
return ret;
}
int add(int *a,int x,int d){
while(x<maxn){
a[x]+=d; x+=lowbit(x);
}
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++){
scanf("%d %d",&cow[i].v,&cow[i].x);
}
sort(cow,cow+n);
LL ans=0; LL pre_sum=0;
for(int i=0;i<n;i++){
int x=cow[i].x; int v=cow[i].v;
int cnt=sum(cnt_num,x);
int dist=sum(cnt_dit,x);
ans+=(LL)v*( cnt*x-dist + pre_sum-(i-cnt)*x-dist );
add(cnt_num,x,1);
add(cnt_dit,x,x);
pre_sum+=x;
}
printf("%lld\n",ans);
}
return 0;
}