zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    flex + bison multiple parsers
    Educational Codeforces Round 95 (Rated for Div. 2)
    python学习笔记 day20 序列化模块(二)
    python学习笔记 day20 常用模块(六)
    python 学习笔记 常用模块(五)
    python学习笔记 day19 常用模块(四)
    python学习笔记 day19 常用模块(三)
    python学习笔记 day19 常用模块(二)
    python学习笔记 day19 作业讲解-使用正则表达式实现计算器
    python学习笔记 day19 常用模块
  • 原文地址:https://www.cnblogs.com/fzl194/p/8955028.html
Copyright © 2011-2022 走看看