zoukankan      html  css  js  c++  java
  • 【codevs1082】线段树练习3——树状数组(改段求段)

    题目链接

    经典的改段求段模型,题目都告诉你要用线段树做了,当然这种操作用树状数组来写就够了。

    这里需要用到两个辅组数组X和Y,每次操作时,相当于:

      X[l]+=val;X[r+1]-=val;Y[l]+=-1*val*(l-1);Y[r+1]+=r*val;

    以上修改代价是O(logn)的。

    对于求1~l的和,答案就是:

      get_sum(l)=X.sum(l)*l+Y.sum(l)

    那么每次查询的答案就是:

      get_sum(r)-get_sum(l-1)

    解释:

    首先X.sum(l)与改段求点型类似,为l这个点增加的值,也就是说X.sum(l)*l表示如果把前l个数增加的值都看成和l相同的话答案是多少。

    但是前l个点增加的值显然不一定和l相同啊,咋办咧?

    这时候就要看式子的后半部分Y.sum(l)了:

      Y.sum(l)相当于求出前l个数增加的部分有多少是被算多的了,因为之前已经先*-1了所以直接加上就好。

    查询代价O(logn),和线段树相同。

    特别的,l-1可能为0,需要特判。

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<queue>
     5 #define lowbit(x) x&-x
     6 typedef long long LL;
     7 const int N=2e5+10;
     8 LL n,q,a[N],X[N],Y[N];
     9 int read(){
    10     int ans=0,f=1;char c=getchar();
    11     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    12     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
    13     return ans*f;
    14 }
    15 LL sum(int r,LL c[]){
    16     LL ans=0;
    17     if(!r)ans=c[0];
    18     for(int i=r;i;i-=lowbit(i))ans+=c[i];
    19     return ans;
    20 }
    21 void add(int r,int v,LL c[]){
    22     if(!r){c[0]+=v;return;}
    23     for(;r<=n;r+=lowbit(r))c[r]+=v;
    24 }
    25 LL get_sum(int x){return sum(x,X)*x+sum(x,Y);}
    26 int main(){
    27     n=read();
    28     for(int i=1;i<=n;i++)a[i]=a[i-1]+read();
    29     q=read();
    30     while(q--){
    31         int op=read(),l=read(),r=read(),v;
    32         if(!(op-1)){
    33             v=read();
    34             add(l,v,X);add(r+1,-v,X);add(l,-1*v*(l-1),Y);add(r+1,r*v,Y);
    35         }
    36         else printf("%lld
    ",get_sum(r)-get_sum(l-1)+a[r]-a[l-1]);
    37     }
    38     return 0;
    39 }
    codevs1082
  • 相关阅读:
    HDU2586 How far away?(tarjan的LCA)
    You Raise Me Up
    POJ2891 Strange Way to Express Integers(中国剩余定理)
    POJ2142 The Balance(扩展欧几里得)
    HDU 1166模仿大牛写的线段树
    NetWord Dinic
    HDU 1754 线段树裸题
    hdu1394 Minimum Inversion Number
    hdu2795 Billboard
    【完全版】线段树
  • 原文地址:https://www.cnblogs.com/JKAI/p/7665069.html
Copyright © 2011-2022 走看看