思路:
把奶牛按照v排序;
然后,每次都把奶牛放入一个集合s;
因为奶牛已经排序;
所以,每次第i次放入奶牛起作用的v就是vi;
每次ans+=(xi*sum-sumxl)*vi+(sumxr-xi*sum)*vi;
可以用线段树实现;
来,上代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 20005 struct CowType { int vi,xi; }; struct CowType cow[maxn]; struct TreeNodeType { int l,r,xx,sum,mid; }; struct TreeNodeType tree[maxn<<2]; int n; long long ans,sx,ss; inline void in(int &now) { char Cget=getchar();now=0; while(Cget>'9'||Cget<'0') Cget=getchar(); while(Cget>='0'&&Cget<='9') { now=now*10+Cget-'0'; Cget=getchar(); } } bool cmp(CowType aa,CowType bb) { return aa.vi<bb.vi; } void tree_build(int now,int l,int r) { tree[now].l=l,tree[now].r=r; if(l==r) return ; tree[now].mid=l+r>>1; tree_build(now<<1,l,tree[now].mid); tree_build(now<<1|1,tree[now].mid+1,r); } void tree_add(int now,int to) { if(tree[now].l==tree[now].r) { tree[now].sum++; tree[now].xx+=cow[to].xi; return ; } if(cow[to].xi<=tree[now].mid) tree_add(now<<1,to); else tree_add(now<<1|1,to); tree[now].xx=tree[now<<1].xx+tree[now<<1|1].xx; tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum; } void tree_query(int now,int l,int r) { if(tree[now].l==l&&tree[now].r==r) { sx+=tree[now].xx,ss+=tree[now].sum; return ; } if(l>tree[now].mid) tree_query(now<<1|1,l,r); else if(r<=tree[now].mid) tree_query(now<<1,l,r); else { tree_query(now<<1,l,tree[now].mid); tree_query(now<<1|1,tree[now].mid+1,r); } } int main() { in(n); for(int i=1;i<=n;i++) in(cow[i].vi),in(cow[i].xi); sort(cow+1,cow+n+1,cmp),tree_build(1,0,20001),tree_add(1,1); for(int i=2;i<=n;i++) { tree_add(1,i); sx=0,ss=0,tree_query(1,0,cow[i].xi-1); ans+=(ss*cow[i].xi-sx)*cow[i].vi; sx=0,ss=0,tree_query(1,cow[i].xi+1,20001); ans+=(sx-ss*cow[i].xi)*cow[i].vi; } cout<<ans; return 0; }