zoukankan      html  css  js  c++  java
  • POJ 1990 MooFest (树状数组)

    题意:由n头牛,不同的听力值v,当i,j想要通话时,需要max(v(i),v(j))*(dist[i]-dist[j])的volume,问这n*(n-1)/2对牛总共的volume时多少。

    思路:非常好的一道树状数组,自己想了很长时间没想起来,最后看了结题报告才恍然大悟,对n头牛按v进行排序,由小到大,tre_sumx[i.x]记录前i头牛于x的坐标的总和,tre_cnt[i.x]记录前i头牛坐标低于x的牛的头数,total记录前i头牛的总x和,那么对于每个牛,依靠这三个量就可以计算出i牛和之前的所有牛的volume和。

    #include <iostream>
    #include
    <cstdio>
    #include
    <algorithm>
    #include
    <memory.h>
    #include
    <cmath>
    #include
    <bitset>
    #include
    <queue>
    #include
    <vector>
    using namespace std;

    const int BORDER = (1<<20)-1;
    const int MAXSIZE = 37;
    const int MAXN = 20100;
    const int INF = 1000000000;
    #define CLR(x,y) memset(x,y,sizeof(x))
    #define ADD(x) x=((x+1)&BORDER)
    #define IN(x) scanf("%d",&x)
    #define OUT(x) printf("%d\n",x)
    #define MIN(m,v) (m)<(v)?(m):(v)
    #define MAX(m,v) (m)>(v)?(m):(v)
    #define ABS(x) ((x)>0?(x):-(x))

    typedef
    struct{
    int v;
    int x;
    }Node;

    Node node[MAXN];
    __int64 tre_cnt[MAXN];
    __int64 tre_sumx[MAXN];
    int n,n_tre;

    bool cmp(const Node& a,const Node& b)
    {
    if(a.v == b.v)
    return a.x < b.x;
    return a.v < b.v;
    }
    int lowbit(int x)
    {
    return x&(-x);
    }
    void modify(__int64* tre,const int& ind,const int& delta)
    {
    for(int i = ind; i <= n_tre; i += lowbit(i))
    tre[i]
    += delta;
    }
    __int64 get_sum(__int64
    * tre, const int& ind)
    {
    __int64 sum
    = 0;
    for(int i = ind; i > 0; i -= lowbit(i))
    sum
    += tre[i];
    return sum;
    }
    int init()
    {
    CLR(tre_cnt,
    0);
    CLR(tre_sumx,
    0);
    n_tre
    = 20005;
    return 0;
    }
    int input()
    {
    for(int i = 0; i < n; ++i)
    {
    scanf(
    "%d%d",&node[i].v,&node[i].x);
    }
    return 0;
    }
    int work()
    {
    int i,j,cnt;
    __int64 ans,sum,total;
    ans
    = 0;
    total
    = 0;
    sort(node,node
    +n,cmp);
    modify(tre_cnt,node[
    0].x,1);
    modify(tre_sumx,node[
    0].x,node[0].x);
    total
    += node[0].x;
    for(i = 1; i < n; ++i)
    {
    sum
    = get_sum(tre_sumx,node[i].x);
    cnt
    = get_sum(tre_cnt,node[i].x);
    ans
    += node[i].v*(node[i].x*((cnt<<1)-i)+total-(sum<<1));
    modify(tre_cnt,node[i].x,
    1);
    modify(tre_sumx,node[i].x,node[i].x);
    total
    += node[i].x;
    }
    cout
    <<ans<<endl;
    return 0;
    }
    int main()
    {
    while(IN(n)!=EOF)
    {
    init();
    input();
    work();
    }
    return 0;
    }


  • 相关阅读:
    如何让你的Sublime和Codeblocks支持C++11
    Python print不换行输出的替代方法
    阶梯博弈
    hdu4633_Polya定理
    Ural_1169_Pairs
    ACM竞赛中的魔方问题专题(不定时更新)
    LintCode 35. 翻转链表
    windows中mysql5.7中配置中文字符集和默认datadir
    CentOS7使用打开关闭防火墙与端口
    关于阿里巴巴开发手册"不得使用外键与级联,一切外键概念必须在应用层解决"的疑惑
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1719150.html
Copyright © 2011-2022 走看看