• poj 1990 MooFest


    题意:

    若干头牛排列在一条坐标轴上(位置都不同),每头牛都有一个音量vi,任意两头牛i,j之间要交流,他们发出的音量就是max(vi,vj) * 它们的距离。

    问n / (n-1)对牛交流的音量的总和。

    思路:

    先无脑n ^ 2了一波,果然tle了,是我太naive。

    首先把牛按照音量递增排序,对于当前的牛,只需要知道数组中在它前面的牛到它的距离的绝对值之和,那么就很好办了。

    关键就是求前面的牛到它的距离的绝对值之和。

    用两个树状数组,一个维护数量的前缀,一个维护位置和的前缀。

    用一个dis来累加当前的距离的总和。

    对于当前的牛,数量树状数组可以求出小于它的位置的牛的个数cnt,位置和树状数组可以求出小于等于它的牛的位置之和sum。

    那么它前面的小于它的位置的牛到它的距离之和就是cnt * x[i] - sum,

    大于它的位置的牛到它的距离之和就是dis - sum - (i - cnt) * x[i]。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 using namespace std;
     5 const int N = 2e5 + 10;
     6 int c[N];
     7 long long d[N];
     8 struct node
     9 {
    10     int v,p;
    11 } a[N];
    12 int mx;
    13 int lowbit(int x)
    14 {
    15     return x&(-x);
    16 }
    17 void addx(int x)
    18 {
    19     for (int i = x;i <= 20000;i += lowbit(i)) c[i]++;
    20 }
    21 int getx(int x)
    22 {
    23     int ans = 0;
    24     for (int i = x;i > 0;i -= lowbit(i)) ans += c[i];
    25     return ans;
    26 }
    27 void addd(int x,int y)
    28 {
    29     for (int i = x;i <= 20000;i += lowbit(i)) d[i] += y;
    30 }
    31 long long getd(int x)
    32 {
    33     long long ans = 0;
    34     for (int i = x;i > 0;i -= lowbit(i)) ans += d[i];
    35     return ans;
    36 }
    37 bool cmp(node aa,node bb)
    38 {
    39     if (aa.v == bb.v) return aa.p < bb.p;
    40     return aa.v < bb.v;
    41 }
    42 int main()
    43 {
    44     int n;
    45     while (scanf("%d",&n) != EOF)
    46     {
    47         memset(c,0,sizeof(c));
    48         memset(d,0,sizeof(d));
    49         long long ans = 0;
    50         for (int i = 0;i < n;i++) scanf("%d%d",&a[i].v,&a[i].p);
    51         sort(a,a+n,cmp);
    52         long long dis = 0;
    53         for (int i = 0;i < n;i++)
    54         {
    55             int cnt = getx(a[i].p);
    56             long long tmp = 0;
    57             long long tmpd = getd(a[i].p);
    58             tmp += 1LL * cnt * a[i].p - tmpd;
    59             tmp += dis - tmpd - 1LL * (i - cnt) * a[i].p;
    60             ans += tmp * a[i].v;
    61             addx(a[i].p);
    62             addd(a[i].p,a[i].p);
    63             dis += a[i].p;
    64         }
    65         printf("%lld
    ",ans);
    66     }
    67     return 0;
    68 }
  • 相关阅读:
    代码对比软件——code compare
    IAR调试和keil调试的一点小区别
    谷访问歌助手
    X86架构的寄存器
    ant-design-pro
    js 闭包 作用域
    《三体》总结
    如何通过SQL注入盗取数据库信息
    《看见》总结
    《欲望的演化》总结
  • 原文地址:https://www.cnblogs.com/kickit/p/9075039.html
Copyright © 2020-2023  润新知