zoukankan      html  css  js  c++  java
  • Codeforces 1030F 【线段树】【好题】

    LINK


    题目大意
    给你n个物品,每一个物品有一个位置p和一个权值w,移动一个物品的代价是移动距离*物品权值
    有q个询问:

    1. 把第i个物品的权值变成j
    2. 问把第l到第r个物品移动到一个相邻的区间中([x,x+r-l]),问你最小的代价

    思路

    首先我们很显然地发现一定是可以固定一个位置不动的,然后把剩下的移动到这个位置附近
    接下来我们考虑怎么找到这个位置
    我们设(S_{(l,r)}=sum_{i=l}^r w_i)
    假设我们现在要固定移动([l,r])这个区间,且区间中的第k个位置不变,现在考虑这个状态移动第k+1个位置不变的差量
    是:(S_{(l,k)}*(p_{k+1}-p_{k})-S_{(k+1,r)}*(p_{k+1}-p_{k}))
    当且仅当(S_{(l,k)}le S_{(k+1,r)})时会使答案更优
    所以就可以找到一个最大的位置k满足上述条件

    接下来考虑怎么计算固定k的代价
    对于(iin (l,k))代价是(sum_{i=l}^k(p_k-p_i-(k-i))*w_i)
    对于(iin (k,r))代价是(sum_{i=k}^r(p_i-p_l-(i-k))*w_i)
    我们令(a_i=p_i-i)
    有:(ans=sum_{i=l}^k(p_k-p_i)*w_i+sum_{i=k}^r(p_i-p_l)*w_i)
    整理一下变成
    (ans=p_k*(S_{l,k}-S_{k,r})-(sum_{i=l}^kw_ip_i-sum_{i=k}^rw_ip_i))
    于是直接开两个线段树分别维护就可以了


    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define IL inline
    #define fu(a,b,c) for(int a=b;a<=c;++a)
    #define fd(a,b,c) for(int a=b;a>=c;--a)
    #define FLIE ""
    IL LL read(){
      LL ans=0,w=1;char c=getchar();
      while(!isdigit(c)&&c!='-')c=getchar();
      if(c=='-')w=-1,c=getchar();
      while(isdigit(c))ans=(ans<<1)+(ans<<3)+c-'0',c=getchar();
      return ans*w;
    }
    #define N 300010
    #define LD (t<<1)
    #define RD (t<<1|1)
    #define Mod 1000000007
    LL sum1[N<<2],sum2[N<<2];
    int a[N],w[N];
    int n,q;
    LL mod(LL a){a%=Mod;if(a<0)a+=Mod;return a;}
    LL add(LL a,LL b){return mod(a+b);}
    LL mul(LL a,LL b){return mod(a*b);}
    void pushup1(int t){sum1[t]=sum1[LD]+sum1[RD];}
    void pushup2(int t){sum2[t]=add(sum2[LD],sum2[RD]);}
    void modify1(int t,int l,int r,int pos,LL vl){
      if(l==r){sum1[t]=vl;return;}
      int mid=(l+r)>>1;
      if(pos<=mid)modify1(LD,l,mid,pos,vl);
      else modify1(RD,mid+1,r,pos,vl);
      pushup1(t);
    }
    void modify2(int t,int l,int r,int pos,LL vl){
      if(l==r){sum2[t]=vl;return;}
      int mid=(l+r)>>1;
      if(pos<=mid)modify2(LD,l,mid,pos,vl);
      else modify2(RD,mid+1,r,pos,vl);
      pushup2(t);
    }
    LL query1_sum(int t,int l,int r,int L,int R){
      if(L<=l&&r<=R)return sum1[t];
      int mid=(l+r)>>1;
      if(R<=mid)return query1_sum(LD,l,mid,L,R);
      if(L>mid)return query1_sum(RD,mid+1,r,L,R);
      return query1_sum(LD,l,mid,L,mid)+query1_sum(RD,mid+1,r,mid+1,R);
    }
    int query1_pos(int t,int l,int r,int L,int R,LL vl){
      if(l==r)return l;
      int mid=(l+r)>>1;
      if(R<=mid)return query1_pos(LD,l,mid,L,R,vl);
      if(L>mid)return query1_pos(RD,mid+1,r,L,R,vl);
      LL suml=query1_sum(LD,l,mid,L,mid);
      if(suml>=vl)return query1_pos(LD,l,mid,L,mid,vl);
      else return query1_pos(RD,mid+1,r,mid+1,R,vl-suml);
    }
    LL query2_sum(int t,int l,int r,int L,int R){
      if(L<=l&&r<=R)return sum2[t];
      int mid=(l+r)>>1;
      if(R<=mid)return query2_sum(LD,l,mid,L,R);
      if(L>mid)return query2_sum(RD,mid+1,r,L,R);
      return add(query2_sum(LD,l,mid,L,mid),query2_sum(RD,mid+1,r,mid+1,R));
    }
    int main(){
      freopen("input.txt","r",stdin);
      n=read();q=read();
      fu(i,1,n)a[i]=read(),a[i]-=i;;
      fu(i,1,n)w[i]=read();
      fu(i,1,n){
        modify1(1,1,n,i,w[i]);
        modify2(1,1,n,i,mul(a[i],w[i]));
      }
      while(q--){
        int x=read(),y=read();
        if(x<0){
          x=-x;
          w[x]=y;
          modify1(1,1,n,x,w[x]);
          modify2(1,1,n,x,mul(a[x],w[x]));
        }else{
          LL sum=query1_sum(1,1,n,x,y);
          int pos=query1_pos(1,1,n,x,y,(sum+1)>>1);
          LL ans=0;
          ans=add(ans,mul(a[pos],add(query1_sum(1,1,n,x,pos),-query1_sum(1,1,n,pos,y))));
          ans=add(ans,add(-query2_sum(1,1,n,x,pos),query2_sum(1,1,n,pos,y)));
          printf("%lld
    ",ans);
        }
      }
      return 0;
    }
    
  • 相关阅读:
    关于JAVA中RSA加签解签,私钥加密公钥解密和公钥加密私钥解密代码详解
    Vue使用总结
    使用ReflectionToStringBuilder实现toString方法
    vue 发送短信验证码倒计时
    个人信息打码
    Token注解防止表单的重复提交
    html选择图片后直接预览
    从分布式一致性谈到CAP理论、BASE理论
    node.js 下依赖Express 实现post 4种方式提交参数
    web前端学习笔记(CSS变化宽度布局)
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9695502.html
Copyright © 2011-2022 走看看