• CodeForces 1058 F Putting Boxes Together 树状数组,带权中位数


    Putting Boxes Together

    题意:

    现在有n个物品,第i个物品他的位置在a[i],他的重量为w[i]。每一个物品移动一步的代价为他的w[i]。目前有2种操作:

    1. x y 将第x的物品的重量改为y

    2.l r 将编号在 [ l, r ]之间的所有物品移动到一起,求最小的花费是多少。

    如果移动一个物品移动一步的代价是1的话,对于[1,n]来说,那么中间位置就是 a[(1+n)/2]. 也就是最中间的那个物品的位置。

    现在移动一步他的代价是w[i],那么中间位置就是 sum(1,k) >= sum(k+1,n) 在满足前面的条件下,k最小。

    我们可以用2分跑出最小的k,这样我们就确定了位置。

    接来下我们的问题就是如何移动物品了。

    我们可以把所有的物品移动到区间[1,n]上,记录下花费。

    然后在把这一整段的物品整体移动到对应区间就好了。

    注意的就是对于中间点来说,整体区间移动的正负是不一样的。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
     4 #define LL long long
     5 #define ULL unsigned LL
     6 #define fi first
     7 #define se second
     8 #define pb push_back
     9 #define lson l,m,rt<<1
    10 #define rson m+1,r,rt<<1|1
    11 #define lch(x) tr[x].son[0]
    12 #define rch(x) tr[x].son[1]
    13 #define max3(a,b,c) max(a,max(b,c))
    14 #define min3(a,b,c) min(a,min(b,c))
    15 typedef pair<int,int> pll;
    16 const int inf = 0x3f3f3f3f;
    17 const LL INF = 0x3f3f3f3f3f3f3f3f;
    18 const LL mod =  (int)1e9+7;
    19 const int N = 2e5 + 100;
    20 LL tree1[N], tree2[N];
    21 int n, q;
    22 int a[N], w[N];
    23 inline int lowbit(int x){
    24     return x & (-x);
    25 }
    26 void add1(int x, LL v){
    27     for(int i = x; i <= n; i+=lowbit(i))
    28         tree1[i] += v;
    29 }
    30 void add2(int x, LL v){
    31     for(int i = x; i <= n; i+=lowbit(i))
    32         tree2[i] += v;
    33 }
    34 LL query1(int x){
    35     LL ret = 0;
    36     for(int i = x; i; i -= lowbit(i))
    37         ret += tree1[i];
    38     return ret;
    39 }
    40 LL query2(int x){
    41     LL ret = 0;
    42     for(int i = x; i; i -= lowbit(i))
    43         ret += tree2[i];
    44     return ret % mod;
    45 }
    46 LL sum1(int l, int r){
    47     if(l > r) return 0;
    48     return query1(r) - query1(l-1);
    49 }
    50 LL sum2(int l, int r){
    51     if(l > r) return 0;
    52     return query2(r) - query2(l-1);
    53 }
    54 int GG(int l, int r){
    55     if(l == r) return 0;
    56     int ll = l, rr = r, mm;
    57     LL tot = sum1(l, r), t1 , t2;
    58     while(ll <= rr){
    59         mm = ll + rr >> 1;
    60         t1 = sum1(l, mm);
    61         t2 = tot - t1;
    62         if(t1 < t2) ll = mm + 1;
    63         else rr = mm - 1;
    64     }
    65     LL ret = 0;
    66     ret -= sum2(l,ll-1);
    67     ret += ((sum1(l,ll-1)%mod) * (a[ll]-1-(ll-1)))%mod;
    68     ret += sum2(ll+1,r);
    69     ret -= ((sum1(ll+1,r)%mod) * (a[ll]+1 -(ll+1)))%mod;
    70     return (ret%mod + mod) % mod;
    71 }
    72 int main(){
    73     scanf("%d%d", &n, &q);
    74     for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    75     for(int i = 1; i <= n; i++){
    76         scanf("%d", &w[i]);
    77         add1(i, w[i]);
    78         LL v = ((1ll*a[i]-i)*w[i])%mod;
    79         add2(i, v);
    80     }
    81     int l, r;
    82     for(int i = 1; i <= q; i++){
    83         scanf("%d%d", &l, &r);
    84         if(l < 0){
    85             l = -l;
    86             add1(l, r-w[l]);
    87             LL v = (((1ll*a[l]-l)*r)%mod)-((1ll*a[l]-l)*w[l])%mod;
    88             add2(l, v);
    89             w[l] = r;
    90         }
    91         else printf("%d
    ", GG(l,r));
    92     }
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    转-jsonp和jsonpcallback的使用
    转-jQuery jsonp跨域请求
    转-彻底弄懂JS的事件冒泡和事件捕获
    转-打造自己的js类库
    (转)JavaScript: 零基础轻松学闭包(1)
    Myslq 之主键
    Myslq 之空值与非空
    Myslq 之记录查找
    Myslq 之插入记录
    Myslq 之查看数据表
  • 原文地址:https://www.cnblogs.com/MingSD/p/9718442.html
Copyright © 2020-2023  润新知