zoukankan      html  css  js  c++  java
  • CF1030F Putting Boxes Together

    CF1030F - Putting Boxes Together

    题意:给定数轴上的n个物体,你要把第l个物体到第r个物体之间的所有物体挪到挨在一起,使得总消耗最小。带修。消耗是重量乘距离。

    解:就是带权中位数。有个结论是一定有一个物体不动。还有一个结论是不动的物体左右两边权值和之差最小。

    于是我们先找到那个不动位置,然后计算把别的挪过去的消耗。

    找它就先查权值和,先+1然后除以2,然后找到那个位置。

    计算消耗就维护一个全挪到最左最右的消耗,一个从最左最右散开的消耗,然后跟sum加加减减一下。不需要在线段树上维护很多东西。

      1 /** CF 1030F */
      2 #include <bits/stdc++.h>
      3 
      4 typedef long long LL;
      5 
      6 const int N = 200010, MO = 1e9 + 7;
      7 
      8 LL sum[N << 2], tr[N << 2], tl[N << 2], w[N];
      9 int X[N], xx, a[N], n;
     10 
     11 inline void Add(int &a, const int &b) {
     12     a += b;
     13     if(a >= MO) a -= MO;
     14     if(a < 0) a += MO;
     15     return;
     16 }
     17 
     18 struct TA {
     19     int ta[N];
     20     inline void add(int i, int v) {
     21         for(; i <= n; i += i & (-i)) {
     22             Add(ta[i], v);
     23         }
     24         return;
     25     }
     26     inline int ask(int i) {
     27         int ans = 0;
     28         for(; i; i -= i & (-i)) {
     29             Add(ans, ta[i]);
     30         }
     31         return ans;
     32     }
     33     inline int getSum(int l, int r) {
     34         return (ask(r) - ask(l - 1) + MO) % MO;
     35     }
     36 }ta1, ta2, ta3, ta4;
     37 
     38 inline void pushup(int l, int r, int o) {
     39     int ls = o << 1, rs = ls | 1, mid = (l + r) >> 1;
     40     sum[o] = sum[ls] + sum[rs];
     41     tl[o] = tl[ls] + tl[rs] + sum[rs] * (X[mid + 1] - X[l] - (mid - l + 1));
     42     tr[o] = tr[ls] + tr[rs] + sum[ls] * (X[r] - X[mid] - (r - mid));
     43     return;
     44 }
     45 
     46 void build(int l, int r, int o) {
     47     if(l == r) {
     48         sum[o] = w[r];
     49         return;
     50     }
     51     int mid = (l + r) >> 1;
     52     build(l, mid, o << 1);
     53     build(mid + 1, r, o << 1 | 1);
     54     pushup(l, r, o);
     55     return;
     56 }
     57 
     58 void change(int p, int v, int l, int r, int o) {
     59     if(l == r) {
     60         sum[o] = v;
     61         return;
     62     }
     63     int mid = (l + r) >> 1;
     64     if(p <= mid) {
     65         change(p, v, l, mid, o << 1);
     66     }
     67     else {
     68         change(p, v, mid + 1, r, o << 1 | 1);
     69     }
     70     pushup(l, r, o);
     71     return;
     72 }
     73 
     74 LL getSum(int L, int R, int l, int r, int o) {
     75     if(L <= l && r <= R) {
     76         return sum[o];
     77     }
     78     int mid = (l + r) >> 1;
     79     LL ans = 0;
     80     if(L <= mid) {
     81         ans = getSum(L, R, l, mid, o << 1);
     82     }
     83     if(mid < R) {
     84         ans += getSum(L, R, mid + 1, r, o << 1 | 1);
     85     }
     86     return ans;
     87 }
     88 
     89 int getPos(LL k, int l, int r ,int o) {
     90     if(l == r) {
     91         return r;
     92     }
     93     int mid = (l + r) >> 1;
     94     if(k <= sum[o << 1]) {
     95         return getPos(k, l, mid, o << 1);
     96     }
     97     else {
     98         return getPos(k - sum[o << 1], mid + 1, r, o << 1 | 1);
     99     }
    100 }
    101 
    102 int Ask(int x, int y) {
    103     LL sum = getSum(x, y, 1, n, 1);
    104     LL sum2 = 0;
    105     if(x > 1) sum2 = getSum(1, x - 1, 1, n, 1);
    106     LL delta = sum2 + ((sum + 1) >> 1);
    107     int p = getPos(delta, 1, n, 1);
    108     int ans = 0;
    109     if(x < p) {
    110         LL Sum = getSum(x, p - 1, 1, n, 1) % MO;
    111         Add(ans, ((LL)ta3.getSum(x, p - 1) - ta4.getSum(x, p - 1) - Sum * (X[n] - X[p] - (n - p)) % MO) % MO);
    112     }
    113     if(p < y) {
    114         LL Sum = getSum(p + 1, y, 1, n, 1) % MO;
    115         Add(ans, ((LL)ta1.getSum(p + 1, y) - ta2.getSum(p + 1, y) - Sum * (X[p] - X[1] - (p - 1))) % MO);
    116         //printf("%d %d %lld * %d
    ", ta1.getSum(p + 1, y), ta2.getSum(p + 1, y), Sum, (X[p] - X[1] - (p - 1)));
    117     }
    118     return ans;
    119 }
    120 
    121 int main() {
    122     
    123     int q;
    124     scanf("%d%d", &n, &q);
    125     for(int i = 1; i <= n; i++) {
    126         scanf("%d", &X[i]);
    127     }
    128     for(int i = 1; i <= n; i++) {
    129         scanf("%lld", &w[i]);
    130     }
    131     build(1, n, 1);
    132     for(int i = 1; i <= n; i++) {
    133         LL c = w[i];
    134         ta1.add(i, c * (X[i] - X[1]) % MO);
    135         ta2.add(i, c * (i - 1) % MO);
    136         ta3.add(i, c * (X[n] - X[i]) % MO);
    137         ta4.add(i, c * (n - i) % MO);
    138     }
    139 
    140     int x, y;
    141     for(int i = 1; i <= q; i++) {
    142         scanf("%d%d", &x, &y);
    143         if(x < 0) {
    144             x = -x;
    145             change(x, y, 1, n, 1);
    146             int dt = (y - w[x] + MO) % MO;
    147             ta1.add(x, (LL)dt * (X[x] - X[1]) % MO);
    148             ta2.add(x, (LL)dt * (x - 1) % MO);
    149             ta3.add(x, (LL)dt * (X[n] - X[x]) % MO);
    150             ta4.add(x, (LL)dt * (n - x) % MO);
    151             w[x] = y;
    152         }
    153         else {
    154             int ans = Ask(x, y);
    155             printf("%d
    ", ans);
    156         }
    157     }
    158 
    159     return 0;
    160 }
    AC代码
  • 相关阅读:
    实验三 进程调度模拟程序
    实验二作业调度模拟程序实验报告
    实验8
    实验七
    实验六
    实验五 数独游戏界面设置
    实验五
    实验四
    实验三
    实验二
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/11063646.html
Copyright © 2011-2022 走看看