zoukankan      html  css  js  c++  java
  • POJ1990 MooFest

      POJ1990 MooFest
    Time Limit: 1000MS Memory Limit: 30000K
    Total Submissions: 3400 Accepted: 1330

    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 

    * 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. 

    Output

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

    Sample Input

    4
    3 1
    2 5
    2 6
    4 3
    

    Sample Output

    57
    

    Source

    *****************************************************************************
    题目大意:一群牛参加完牛的节日后都有了不同程度的耳聋,第i头牛听见别人的讲话,别人的音量必须大于v[i],当两头牛i,j交流的时候,交流的最小声音为max{v[i],v[j]}*他们之间的距离。现在有n头牛,求他们之间两两交流最少要的音量和。
    解题思路:一开始水水的写了一个n^2的算法,这题终究没有那么白痴。原来是用了树状数组。首先将这n头牛按照v值从小到大排序(后面说的排在谁的前面,都是基于这个排序)。这样,排在后面的牛和排在前面的牛讲话,两两之间所用的音量必定为后面的牛的v值,这样一来才有优化的余地。然后,对于某头牛i来说,只要关心跟排在他前面的牛交流就好了。我们必须快速地求出排在他前面的牛和他之间距离的绝对值只和ans,只要快速地求出ans,就大功告成。这里需要两个树状数组。树状数组可以用来快速地求出某个区间内和,利用这个性质,我们可以快速地求出对于牛i,x位置比i小牛的个数,以及这个牛的位置之和。这里就需要两个树状数组,一个记录比x小的牛的个数a,一个记录比x小的牛的位置之和b,然后,我们可以快速地求出牛i和比牛i位置小的牛的所有距离的绝对值为:a*x[i]-b;也可以方便地求出比牛i位置大的牛到牛i的距离和,即所有距离-b-(i-1-a)*x[i];那么此题就差不多了。
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #define MAX(a,b) (a>b?a:b)
    #define ABS(a) ((a)>0?(a):-1*(a))
    #define TK(a) (a&(a^(a-1)))
    #define N 20005
    using namespace std;
    
    struct Node
    {
        long long v,x;
        bool operator<(const Node & a)const
        {
            return v<a.v;
        }
    }node[N];
    
    long long num[2][N];
    
    long long rsum(int pos,int d)
    {
        long long ans=0;
        while(pos>0)
        {
            ans+=num[d][pos];
            pos-=TK(pos);
        }
        return ans;
    }
    
    void toput(int pos,long long v,int d)
    {
        while(pos<=20000)
        {
            num[d][pos]+=v;
            pos+=TK(pos);
        }
    }
    
    int main()
    {
        int n;
        scanf("%d",&n);
        memset(num,0,sizeof(num));
        for(int i=1;i<=n;i++)
            scanf("%lld%lld",&node[i].v,&node[i].x);
        sort(node+1,node+1+n);
        long long ans=0;
        for(int i=1;i<=n;i++)
        {
            long long a=rsum(node[i].x,0),b=rsum(node[i].x,1);
            ans+=(node[i].x*a-b+rsum(20000,1)-b-(i-1-a)*node[i].x)*node[i].v;
            toput(node[i].x,1,0);
            toput(node[i].x,node[i].x,1);
        }
        printf("%lld\n",ans);
    }
    

      

  • 相关阅读:
    用两个栈实现队列
    重建二叉树
    从尾到头打印链表
    替换空格
    字符串比较
    二维数组的查找
    ORACLE---Unit01: 数据库原理 、 SQL(DDL、DML)
    [Python]小甲鱼Python视频第035课(图形用户界面入门:EasyGui)课后题及参考解答
    [Python]小甲鱼Python视频第032课(异常处理:你不可能总是对的)课后题及参考解答
    [Python]小甲鱼Python视频第030课(文件系统:介绍一个高大上的东西)课后题及参考解答
  • 原文地址:https://www.cnblogs.com/Fatedayt/p/2202439.html
Copyright © 2011-2022 走看看