• 树状数组的修炼 疑惑篇


    洛谷p2345

    奶牛叫不出の痛

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int maxn = 2e5 + 10;
     5 int n;
     6 ll cnt[maxn];//cnt[i]表示i位置及其左侧牛的个数 
     7 ll sum[maxn];
     8 ll res = 0;
     9 ll mx = 0;
    10 struct cow
    11 {
    12     ll x, v;
    13     bool operator < (const cow &a){
    14         return v < a.v;
    15     }
    16 };
    17 cow a[maxn]; 
    18 
    19 int lowbit(int x)
    20 {
    21     return x & -x;
    22 }
    23 
    24 void updcnt(int x, int val)
    25 {
    26     for(int i = x ; i <= mx ; i += lowbit(i)){
    27         cnt[i] += val;
    28     }
    29 }
    30 
    31 void updsum(int x, ll val)
    32 {
    33     for(int i = x ; i <= mx ; i += lowbit(i)){
    34         sum[i] += val;
    35     }
    36 }
    37 
    38 ll getcnt(int x)
    39 {
    40     ll tmp = 0;
    41     for(int i = x ; i >= 1 ; i -= lowbit(i)){
    42         tmp += cnt[i];
    43     }
    44     return tmp;
    45 }
    46 
    47 ll getsum(int x)//求原点到x的所有存在的点的距离 
    48 {
    49     ll s = 0;
    50     for(int i = x ; i >= 1 ; i -= lowbit(i)){
    51         s += sum[i];
    52     }
    53     return s;
    54 }
    55 
    56 int main(){
    57     scanf("%d",&n);
    58     for(int i = 1 ; i <= n ; i++){
    59         scanf("%lld%lld",&a[i].v,&a[i].x);
    60         mx = max(mx, a[i].x);//最远距离 
    61     }
    62     sort(a + 1, a + n + 1);
    63     
    64     updcnt(a[1].x, 1);
    65     updsum(a[1].x, a[1].x);
    66     for(int i = 2 ; i <= n ; i++){//
    67         updcnt(a[i].x, 1);
    68         updsum(a[i].x, a[i].x);
    69         ll cl = getcnt(a[i].x - 1), cr = getcnt(mx) - getcnt(a[i].x);//cnt of left/right
    70         ll sl = getsum(a[i].x - 1), sr = getsum(mx) - getsum(a[i].x);//sum of left/right
    71         res += a[i].v * (sr - cr * a[i].x + a[i].x * cl - sl);
    72     }
    73     printf("%lld
    ",res);
    74     
    75     return 0;
    76 }

    上来纠结了一会,但还是有点思路方向的。

    将距离分类为该点左侧以及右侧进行处理。

    每次更新一头奶牛,分别用树状数组维护记录cnt和sum,写两个upd和get。

    但是代码就是想半天写不出。很棘手的问题。。。或许是因为思路不够清晰?还是要明确维护操作的细节才行啊。

    欸。。。继续刷题(研究题解)吧

  • 相关阅读:
    使用Bat自动打包并通过FTP发送到备份服务器——实战测试
    什么是STP
    【基础】华为单臂路由技术配置记录
    Windows Server 2012系统上安装.net framework3.5教程
    eNSP启动设备AR1失败记一次解决步骤
    Linux系统设置 SSH 通过密钥登录
    windows和linux修改ipv6和ipv4的优先级
    思科交换机配置中继
    【Nginx】Nginx反向代理转发Host设置
    idea查看类的uml图
  • 原文地址:https://www.cnblogs.com/ecustlegendn324/p/13777406.html
Copyright © 2020-2023  润新知