zoukankan      html  css  js  c++  java
  • POJ 1990 MooFest

    每年,农夫约翰的N(1 <= N <= 20,000)只牛会参加“MooFest”,一个来自世界各地的牛的社交聚会。 MooFest有许多活动,包括干草堆积,篱笆跳跃,把尾巴钉在农夫的身上...当奶牛都站在同一个地方排队,他们会大声喊叫,吼声几乎震耳欲聋。事实上,每年参加了这个活动后,一些奶牛已经失去了部分听力。 

    每个奶牛具有耳背值v(i)(在1..20,000的范围内)。如果一头牛向牛i吼叫,她必须使用至少是两头母牛之间距离的v(i)倍的声音,以便被牛i听到。如果两个奶牛i和j想要交谈,她们必须以等于她们之间的距离乘以max(v(i),v(j))的音量说话。 

    假设N头奶牛中的每头奶牛都站在直线上(每头奶牛在1..20,000范围内的某个独特x坐标),每对奶牛都使用尽可能小的声音进行谈话。 

    计算所有N(N-1)/ 2对正在说话的奶牛产生的所有声音的总和。 
    Input
    *第1行:单个整数,N 

    *第2到N + 1行:两个整数:牛的耳背值v和x坐标。第2行代表第一头牛;第3行表示第二头牛;等等。没有两头牛会站在同一个位置。 
    Output
    *第1行:仅含单个整数,表示所有牛互相吼叫的所有声音的总和。 
    Sample Input
    4
    3 1
    2 5
    2 6
    4 3
    Sample Output
    57

    思路:当两头牛进行计算时,用到的是V值大的牛。所以先按照V值从大到小排序,当计算某头牛时,只考虑V值比它小的那些牛。我们用两个树状数组分别表示牛的坐标之和及牛的数量之和(以坐标作为数组下标)。那么考虑牛i时(按V从大到小排序后),设坐标值比它小的那些牛的数目为num1、坐标之和为sum1,坐标值比它大的那些牛的数目为num2、坐标之和为sum2,那么对该牛而言(设坐标为X,体力值为V),所贡献的答案为V * ( X*num1-sum1 + sum2-X*num2 )。

    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    #include <stdlib.h>
    #include <string>
    #include <string.h>
    #include <math.h>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    
    
    #define INF 0x3f3f3f3f
    #define LL long long
    using namespace std;
    const int  MAXN = 2e5+5;
    
    struct Node{
        int x;
        int val;
    };
    
    int c1[MAXN],c2[MAXN];
    Node a[MAXN];
    int n;
    
    
    
    bool cmp(Node a,Node b)
    {
        return a.val>b.val;
    }
    
    int lowbit(int x)
    {
        return x & (-x);
    }
    
    void updata(int a[],int x,int v)
    {
        while (x<MAXN)
        {
            a[x] += v;
            x += lowbit(x);
        }
    }
    
    int getsum(int a[],int x)
    {
        int res = 0;
        while (x)
        {
            res += a[x];
            x -= lowbit(x);
        }
        return res;
    }
    
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
        {
            scanf("%d%d",&a[i].val,&a[i].x);
            updata(c1,a[i].x,a[i].x);
            updata(c2,a[i].x,1);
        }
        sort(a+1,a+1+n,cmp);
        LL ans = 0;
        for (int i=1;i<=n;i++)
        {
            updata(c1,a[i].x,-a[i].x);
            updata(c2,a[i].x,-1);
            int sum1 = getsum(c1,a[i].x);
            int sum2 = getsum(c1,MAXN)-sum1;
            int num1 = getsum(c2,a[i].x);
            int num2 = getsum(c2,MAXN)-num1;
            ans += (LL)(abs(a[i].x*num1-sum1)+abs(sum2-a[i].x*num2))*a[i].val;
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    Windows8 Metro界面下的StreamSocket连接服务器
    使用CSS控制文字溢出
    Javascript中的恒等运算符与等于运算符的区别
    Sqlserver 中删除表数据的两种方式与区别
    Linux C++ 遇到的错误
    四、Vue Router 设置动态路由
    六、Vue Router 嵌套路由
    一、Vue Router 的使用
    三、Vuex Getter
    五、Vuex Action
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11267296.html
Copyright © 2011-2022 走看看