
/**//*
題意:給出一條直線上的點(diǎn),每個(gè)點(diǎn)xi有值vi 每一對(duì)(i,j)的值為:dis(ti,j)*max(vi,vj)
現(xiàn)求所有C(N,2)對(duì)點(diǎn)的所有值 O(n^2)會(huì)Tle
先按照V排序!
用兩個(gè)一維樹(shù)狀數(shù)組,分別記錄小于xi的點(diǎn)的個(gè)數(shù)pre_cnt以及小于xi點(diǎn)的距離之和pre_dist
對(duì)于i之前的點(diǎn)xj,分xj<xi和xj>xi計(jì)算:
ans+=(long long)v*(pre_cnt*x-pre_dist + total_dist-pre_dist-(i-pre_cnt)*x);
total_dist為i-1個(gè)點(diǎn)的x坐標(biāo)之和
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int MAXN = 20000;

struct Cow


{
int v,x;
bool operator<(const Cow &c)const

{
return v<c.v;
}
}cows[MAXN+5];

int cnt_C[MAXN+5],dist_C[MAXN+5];
int N;


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

void insert(int *a,int p,int x)


{
while(p<=MAXN)

{
a[p]+=x;
p+=lowbit(p);
}
}

int sum(int *a,int p)


{
int ans = 0;
while(p>0)

{
ans+=a[p];
p-=lowbit(p);
}
return ans;
}

int main()


{
while(~scanf("%d",&N))

{
for(int i=0;i<N;i++)
scanf("%d%d",&cows[i].v,&cows[i].x);
sort(cows,cows+N);
long long ans = 0;
int total_dist = 0;
for(int i=0;i<N;i++)

{
int x = cows[i].x,v=cows[i].v;
int pre_dist = sum(dist_C,x),pre_cnt = sum(cnt_C,x);//no two in the same pos
ans+=(long long)v*(pre_cnt*x-pre_dist + total_dist-pre_dist-(i-pre_cnt)*x);//i從0開(kāi)始
insert(dist_C,x,x);
insert(cnt_C,x,1);
total_dist+=x;
}
printf("%lld\n",ans);
}
return 0;
}
hdu 3015 跟這個(gè)類(lèi)似,不過(guò)要先離散化