1015(树状数组+数学运算)

来源:互联网 发布:ubuntu怎么dakaiexe 编辑:程序博客网 时间:2024/06/06 10:53

Problem Description
Every year, Farmer John's N (1 <= N <= 20,000) cows attend "MooFest",a social gathering of cows from around the world. MooFest involves a variety of events including haybale stacking, fence jumping, pin the tail on the farmer, and of course, mooing. When the cows all stand in line for a particular event, they moo so loudly that the roar is practically deafening. After participating in this event year after year, some of the cows have in fact lost a bit of their hearing.

Each cow i has an associated "hearing" threshold v(i) (in the range 1..20,000). If a cow moos to cow i, she must use a volume of at least v(i) times the distance between the two cows in order to be heard by cow i. If two cows i and j wish to converse, they must speak at a volume level equal to the distance between them times max(v(i),v(j)).

Suppose each of the N cows is standing in a straight line (each cow at some unique x coordinate in the range 1..20,000), and every pair of cows is carrying on a conversation using the smallest possible volume.

Compute the sum of all the volumes produced by all N(N-1)/2 pairs of mooing cows.

Input
* Line 1: A single integer, N <br> <br>* Lines 2..N+1: Two integers: the volume threshold and x coordinate for a cow. Line 2 represents the first cow; line 3 represents the second cow; and so on. No two cows will stand at the same location. <br>

Output
* Line 1: A single line with a single integer that is the sum of all the volumes of the conversing cows. <br>

Sample Input
43 12 52 64 3

Sample Output
57

题目大概:

两个点之间有一个权值为他们之间最大的音量值,他们之间的价值是距离差乘权值。求所有牛之间的总价值。

思路:

先按照权值不同,升序排序。

两个树状数组,一个算比他小的牛的位置之和,一个计算比他位置小的牛的数量。

然后从权值高的开始计算,价值=比他位置小的点的距离之差*权值+比他位置大的距离之差*权值

最后都加起来。

代码:


#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>using namespace std;long long c[20010][2];struct poin{    long long l,v;}a[20010];int cmp(const poin a,const poin b){    return a.v<b.v;}long long lowbit(long long x){    return x&(-x);}int add(long long x,long long v,int k){    while(x<=20001)    {        c[x][k]+=v;        x=x+lowbit(x);    }}long long sum(long long x,int k){    long long su=0;    while(x>0)    {        su+=c[x][k];        x-=lowbit(x);    }    return su;}int main(){    int t;    while(~scanf("%d",&t))    {    memset(c,0,sizeof(c));    long long ss=0;    for(int i=1;i<=t;i++)   {        long long w1,w2;        scanf("%I64d%I64d",&w1,&w2);        ss+=w2;        a[i].v=w1;a[i].l=w2;        add(w2,1,0);        add(w2,w2,1);    }    sort(a+1,a+t+1,cmp);    long long sun=0;    for(long long i=t;i>0;i--)    {        long long e1=sum(a[i].l-1,0);        long long e2=sum(a[i].l-1,1);        long long sum1,sum2;        long long w1,w2;        w1=t-e1-1; w2=ss-e2-a[i].l;        sum1=(e1*a[i].l-e2)*a[i].v;        sum2=(w2-w1*a[i].l)*a[i].v;        sun+=sum1+sum2;        add(a[i].l,-1,0);        add(a[i].l,-a[i].l,1);        t--;        ss=ss-a[i].l;    }    printf("%I64d\n",sun);    }    return 0;}




原创粉丝点击