• POJ-1990 MooFest---两个树状数组


    题目链接:

    https://vjudge.net/problem/POJ-1990

    题目大意:

    一群牛参加完牛的节日后都有了不同程度的耳聋,第i头牛听见别人的讲话,别人的音量必须大于v[i],当两头牛i,j交流的时候,交流的最小声音为max{v[i],v[j]}*他们之间的距离。现在有n头牛,求他们之间两两交流最少要的音量和。

    解题思路:

    使用树状数组,首先将二元组按照v的大小从小到大排序,这样可以保证每头牛比前面的牛的v大,计算它和它前面牛的音量和的时候,就可以直接用该头牛的v,还需要计算出|a[i].x - x|绝对值之和。

    用树状数组维护坐标x,可以直接求出比这头牛小的所有x之和,还需要用另一个树状数组维护每个元素出现的次数,直接求出小于这头牛的x的牛的数目。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<map>
     6 #include<set>
     7 #include<cmath>
     8 #include<algorithm>
     9 #include<vector>
    10 #include<sstream>
    11 #define lowbot(i) (i&(-i))
    12 using namespace std;
    13 typedef long long ll;
    14 const int maxn = 1e5 + 10;
    15 struct cow
    16 {
    17     ll v, x;
    18     bool operator <(const cow& a)const
    19     {
    20         return v < a.v || v == a.v && x < a.x;
    21     }
    22 }a[maxn];
    23 int tree[maxn], id_num[maxn];
    24 void add(int x, int d, int tree[])
    25 {
    26     while(x <= maxn)//上限是maxn
    27     {
    28         tree[x] += d;
    29         x += lowbot(x);
    30     }
    31 }
    32 ll sum(int x, int tree[])
    33 {
    34     ll ans = 0;
    35     while(x)
    36     {
    37         ans += tree[x];
    38         x -= lowbot(x);
    39     }
    40     return ans;
    41 }
    42 int main()
    43 {
    44     int n;
    45     scanf("%d", &n);
    46     for(int i = 0; i < n; i++)scanf("%lld%lld", &a[i].v, &a[i].x);
    47     sort(a, a + n);
    48     ll num, tot, ans = 0;
    49     for(ll i = 0; i < n; i++)
    50     {
    51         num = sum(a[i].x, id_num);
    52         tot = sum(a[i].x, tree);
    53         ans += (num * a[i].x - tot) * a[i].v;
    54         //cout<<num<<" - "<<tot<<" + "<<ans<<endl;
    55         num = i - num;
    56         tot = sum(20000, tree) - tot;
    57         ans += (tot - num * a[i].x) * a[i].v;
    58         //cout<<num<<" - "<<tot<<" - "<<ans<<endl;
    59         add(a[i].x, a[i].x, tree);
    60         add(a[i].x, 1, id_num);
    61     }
    62     cout<<ans<<endl;
    63     return 0;
    64 }
  • 相关阅读:
    最小生成树之 Prim 算法
    Linux通过ps命令找到进程并kill当前进程
    M6G2C Cortex®A7工控核心板SIMCOM4G模块移植流程
    Spring事件监听机制源码解析
    Pytorch损失函数总结
    目标检测任务理解与总结
    [炼丹术]EfficientDet训练模型学习总结
    [炼丹术]DeepLabv3+训练模型学习总结
    可视化经典模型的对比实验总结
    基于COCO数据集验证的目标检测算法天梯排行榜
  • 原文地址:https://www.cnblogs.com/fzl194/p/8955028.html
Copyright © 2020-2023  润新知