zoukankan      html  css  js  c++  java
  • ACM-ICPC 2018 徐州赛区网络预赛 H Ryuji doesn't want to study (树状数组差分)

    https://nanti.jisuanke.com/t/31460

    题意

    两个操作。1:查询区间[l,r]的和,设长度为L=r-l+1, sum=a[l]*L+a[l+1]*(L-1)+...+a[r]。2:将第a个位置修改为b。

    分析

    变形一下,sum=a[l]*(r-l+1)+a[l+1]*(r-(l+1)-1)+...+a[r](r-r+1)=(r+1)*a[l]-a[l]*l。因此,可维护两个树状数组计算。至于更新操作,实质就是看变化前后的差值,变大就相当与加上差值,否则就是减。注意用longlong

    #include<bits/stdc++.h>
    const int maxn = 1e5 + 10;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    typedef long long ll;
    ll c1[maxn],c2[maxn];
    int a[maxn];
    int lb(int x){ return x&-x; }
    void add(ll c[],int x,ll d){
        while(x<maxn){
            c[x]+=d;
            x+=lb(x);
        }
    }
    ll sum(ll c[],int x){
        ll res=0;
        while(x){
            res+=c[x];
            x-=lb(x);
        }
        return res;
    }
    ll query(int l,int r){
        return (r+1)*(sum(c1,r)-sum(c1,l-1))-(sum(c2,r)-sum(c2,l-1)); 
    }
    int main(){
        int n,q;
        int op,x,y;
        scanf("%d%d",&n,&q);
         for(int i=1;i<=n;i++) {
            scanf("%d",&x);
            add(c1,i,x);
            add(c2,i,1ll*i*x);
            a[i]=x;
        }
        while(q--){
            scanf("%d%d%d",&op,&x,&y);
            if(op==1){
                printf("%lld
    ",query(x,y));
            }else{
                add(c1,x,y-a[x]);
                add(c2,x,1ll*x*(y-a[x]));
                a[x]=y;
            }
        }
        return 0;
    }
  • 相关阅读:
    图01--[基本概念&&图的实现]
    并查集01--[Quick Find&&Quick Union]
    排序05--[计数排序&&基数排序&&桶排序]
    排序04--[快速排序&&希尔排序]
    harukaの赛前日常
    harukaの收藏夹
    hello world&Restart the Journey
    成外集训小记
    CSPS2019游记
    博弈论初步
  • 原文地址:https://www.cnblogs.com/fht-litost/p/9668515.html
Copyright © 2011-2022 走看看