poj1990

来源:互联网 发布:it技术学校 编辑:程序博客网 时间:2024/06/03 09:59

链接:点击打开链接

题意:给出n头牛的叫声v和坐标x,两头牛如果能够交流则会花费max(v[i],v[j])*abs(x[i]-x[j]),问要使每头牛都能和其它牛交流需要花费多少

代码:

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int SIZE=20005;struct node{    long long v,x;};bool cmp(node a,node b){    return a.v<b.v;}node s[SIZE];long long n,bit[5][SIZE];long long sum(long long i,long long cnt){    long long ans;    ans=0;    while(i>0){        ans+=bit[cnt][i];        i-=i&-i;    }    return ans;}void add(long long i,long long p,long long cnt){    while(i<=20000){                            //以坐标建树,而不是个数        bit[cnt][i]+=p;        i+=i&-i;    }}int main(){    long long i,num,tmp,ans;    while(scanf("%I64d",&n)!=EOF){        ans=0;        memset(bit,0,sizeof(bit));        for(i=1;i<=n;i++)        scanf("%I64d%I64d",&s[i].v,&s[i].x);        sort(s+1,s+n+1,cmp);                    //两头牛能否交流在于较大的那个v,因此按照v排序        for(i=1;i<=n;i++){            num=sum(s[i].x,0);                  //num是比当前这头牛的v小的个数            tmp=sum(s[i].x,1);                  //tmp是比当前这头牛的v小的坐标的和                ans+=((s[i].x*num-tmp)+(sum(20000,1)-tmp-(i-1-num)*s[i].x))*s[i].v;            add(s[i].x,1,0);                    //在这头牛前面的加上这头牛后面的            add(s[i].x,s[i].x,1);        }        printf("%I64d\n",ans);    }    return 0;}


 

0 0