zoukankan      html  css  js  c++  java
  • poj1990 树状数组

    1990

    题意:

    每头牛有两个属性v,x,计算sigma(max(v[i],v[j])*abs(x[i]-x[j]))1<=i<j<=n

    分析:对于max函数我们可以按v的值从小到大排序则ans = sigma(v[j]*abs(x[i]-x[j]))1<=i<j<=n且v[i]<=v[j]

    那么如何处理abs函数呢?分开来讨论

    ans  = sigma(v[j]*(x[i]-x[j]))    x[i]>=x[j]

          + sigma(v[j]*(x[j]-x[i]))   x[i]<x[j]

    如何快速的求得sigma的值呢?树状数组!!

    这样我们就得到了算法:

    先按v值从小到大排序,利用树状数组维护两个数组dist,cnt 其中dist[i] 维护的数坐标(x轴)小于等于i的距离前缀和,cnt[i]表示坐标i在当前时有没有牛(1有,0无),

    维护的是当前排完序后坐标在[1,i]的牛的个数

    那么排完序后枚举当前的牛i 统计在这之前坐标比牛i小的有多少l个,比它大的有多少r个,然后计算牛i到其他牛的权值(以保证牛i是当前以计算牛中v值最大)

    权值= v[i]*( (l*x[i]-dist.sum(x[i]))左边的权值和 +(dist.sum(maxn)-dist.sum(x[i])-r*x[i]) 右边的权值和 )

    其中dist.sum(x[i])表示当前坐标在牛i左边的所有坐标之和,那么l*x[i]就是sigma(x[i]-x[j]) x[i]>=x[j]

    其中dist.sum(maxn)-dist.sum(x[i]) 就是坐标在[x[i],maxn]之间的所有牛的坐标之和  则其-r*x[i] 就是sigma(x[j]-x[i] ) x[i]<x[j]

    每次算完权值后将当前的牛的信息加入树状数组里面

    cnt.add(x[i],1);
    dist.add(x[i],x[i]);

    单点更新 cnt[x[i]]=1,dist[x[i]]=x[i]

    附上代码

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <set>
     5 #include <algorithm>
     6 #include <map>
     7 #include <queue>
     8 #include<cmath>
     9 #include<vector>
    10 #define maxn 100010
    11 #define maxm 100010
    12 #define mod 1000000000000000000
    13 #define INF 0x3f3f3f3f
    14 using namespace std;
    15 typedef long long  ll;
    16 inline int lowbit(int x){
    17     return x&-x;
    18 }
    19 struct BIT{
    20     int n;
    21     ll bit[maxn+10];
    22     void init(int N){
    23         n=N;
    24         for(int i=0;i<=n;++i)bit[i]=0;
    25     }
    26     void add(int x,int v){
    27         for(int i=x;i<=n;i+=lowbit(i))bit[i]+=v;
    28     }
    29     ll  sum(int x){
    30         ll ans=0;
    31         for(int i=x;i>0;i-=lowbit(i))ans+=bit[i];
    32         return ans;
    33     }
    34 }dist,cnt;
    35 pair<int,int>cow[maxn];
    36 int main (){
    37     int n;
    38     while(scanf("%d",&n)!=EOF){
    39         dist.init(maxn);
    40         cnt.init(maxn);
    41         for(int i=1;i<=n;++i){
    42             scanf("%d%d",&cow[i].first,&cow[i].second);
    43         }
    44         sort(cow+1,cow+n+1);
    45         ll ans=0;
    46         for(int i=1;i<=n;++i){
    47             int v = cow[i].first;
    48             int x = cow[i].second;
    49             ll l = cnt.sum(x);//左边已有有多少个
    50             ll r = cnt.sum(maxn)-cnt.sum(x);//右边已有多少个
    51             ans+=v*(l*x-dist.sum(x));//左边权值和
    52             ans+=v*(dist.sum(maxn)-dist.sum(x)-r*x);//右边权值和
    53             cnt.add(x,1);
    54             dist.add(x,x);
    55         }
    56         printf("%lld
    ",ans);
    57     }
    58 }
    View Code
  • 相关阅读:
    【java】对象赋值给另一个对象
    spring boot系列(五)spring boot 配置spring data jpa (查询方法)
    Spring Data JPA 查询
    Spring Data JPA 介绍
    OpenID简介
    OAUTH协议介绍
    URL encoding(URL编码)
    RESTful 介绍
    spring boot系列(四)spring boot 配置spring data jpa (保存修改删除方法)
    spring boot 启动报 java.lang.NoClassDefFoundError: ch/qos/logback/core/spi/LifeCycle 错误
  • 原文地址:https://www.cnblogs.com/shuzy/p/3815281.html
Copyright © 2011-2022 走看看