zoukankan      html  css  js  c++  java
  • 树状数组维护区间加减与查询

    NOIP ,发条题解增加rp;

    树状数组维护区间和。

    令 原数组为a i a1 i为 ai 到 an的共同增量,

    那么 我们要求区间和 等价于求 1到x的和 (可以ask r-ask(l-1));

    ask x =a1+a2+..ax+x*a1 1+(x-1)*a1 2+..a1 x

        =a1+a2+..ax+(x+1)*(a1 1+a1 2+a1 3+...a1 x)-1*a1 1-2*a1 2-3*a1 3...x*a1 x

    那么我们维护 a1 和 i*a1 的数组即可

    下附代码

    #include<bits/stdc++.h>
    #define sight(c) ('0'<=c&&c<='9')
    #define LL long long
    #define gc getchar
    #define getchar nc
    #define L(x) (x&-x)
    #define N 100007
    using namespace std;
    LL a[N],a1[N],a2[N],x,y,k,op,n,m;
    inline char nc(){
        static char buf[1000000],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
    }
    inline void read(LL &x){
        static char c;
        for(c=gc();!sight(c);c=gc());
        for(x=0;sight(c);c=gc()) x=x*10+c-48;
    }
    void write(LL x){if (x<10) {putchar('0'+x);return;}write(x/10); putchar('0'+x%10);}
    inline void change(LL *A,int x,int dla) {for (;x<N;x+=L(x)) A[x]+=dla;}
    inline LL add(LL *A,int x){LL O=0;for(;x;x-=L(x)) O+=A[x];return O;}
    inline LL ask(int r){return a[r]+(r+1)*add(a1,r)-add(a2,r);}
    int main () {
        read(n); read(m);
        for (int i=1;i<=n;i++) read(x),a[i]=a[i-1]+x;
        while (m--) {
            read(op);
            if (op&1) {
                read(x); read(y); read(k);
                change(a1,x,k); change(a1,y+1,-k);
                change(a2,x,k*x); change(a2,y+1,-k*(y+1));
            } else {
                read(x); read(y);
                write(ask(y)-ask(x-1)); putchar('
    ');
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    十大经典排序算法最强总结(含JAVA代码实现)
    Java相关官方链接
    强网杯2020(Funhash)
    强网杯2020(主动)
    强网杯2020(upload)
    (内存取证)46届世界技能大赛湖北省选拔赛
    (流量分析)46届世界技能大赛湖北省选拔赛
    CISCO ASA远程任意文件读取
    OOALV 分割屏幕
    Process Doppelg&#228;nging
  • 原文地址:https://www.cnblogs.com/rrsb/p/7944314.html
Copyright © 2011-2022 走看看