zoukankan      html  css  js  c++  java
  • (模板)区间修改与查询

    题目呀

    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <cstring>
    #define LL long long 
    using namespace std;
    const int MAXN=200001;
    LL a[MAXN];
    struct tree{
        LL adi;
        LL sum;
        LL l;
        LL r;
        LL len;
    }s[MAXN<<2];
    void build(int o,int l,int r)
    { 
        s[o].r=r;s[o].l=l;s[o].len=r-l+1;
        if(l==r) s[o].sum=a[l];
        else 
        {
            int m=l+((r-l)>>1);
            build((o<<1),l,m);
            build((o<<1)+1,m+1,r);
            s[o].sum=s[(o<<1)].sum+s[(o<<1)+1].sum;
        }
    }
    void update(int o,int l,int r,int ind,int ans)
    {
        if(l==r) {s[o].sum=ans;return;}
        int m=l+((r-l)>>1);
        if(ind<=m)
        {
            update((o<<1),l,m,ind,ans);
        }
        else
        {
            update((o<<1)+1,m+1,r,ind,ans);
        }
        s[o].sum=s[(o<<1)].sum+s[(o<<1)+1].sum;
    }
    
    void pushdown(int o)
    {
        int adii=s[o].adi;
        s[(o<<1)].adi+=s[o].adi;
        s[(o<<1)+1].adi+=s[o].adi;
        s[(o<<1)].sum+=adii*s[(o<<1)].len;
        s[(o<<1)+1].sum+=adii*s[(o<<1)+1].len;
        s[o].adi=0;
    }
    void add(int o,int a,int b,int ad)
    {
        int l=s[o].l,r=s[o].r,m=(s[o].l+s[o].r)>>1,len=s[o].len;
        if(l==a&&r==b)    
        {
            s[o].adi+=ad;
            s[o].sum+=len*ad;
            return ;
        }
        if(s[o].adi)    pushdown(o);
        if(b<=m)/*向左分*/   add((o<<1),a,b,ad);//写在下面是不对的
        else if(a>m)/*向右分*/    add((o<<1)+1,a,b,ad);
        else add((o<<1),a,m,ad),add((o<<1)+1,m+1,b,ad);//区间交叉分
        s[o].sum=s[(o<<1)].sum+s[(o<<1)+1].sum;
    }
    LL ask(int o,int a,int b)
    {
        int l=s[o].l,r=s[o].r,m=(s[o].l+s[o].r)>>1;
        if(a==l&&b==r){return s[o].sum;}
        if(s[o].adi)    pushdown(o);//此处需要标记下放
        if(b<=m)    return ask(o<<1,a,b);
        else if(a>m)    return ask(o<<1|1,a,b);
        else return ask(o<<1,a,m)+ask(o<<1|1,m+1,b);//同上
    }
    int main()
    {
        int n,m,i,j;
    
        scanf("%d%d",&n,&m);
    
        for(i=1;i<=n;i++)
         scanf("%lld",&a[i]);
    
        build(1,1,n);
    
        for(i=1;i<=m;i++)
         {
            LL x,a1,b,k;
            scanf("%lld",&x);
            if(x==1) 
            {
                scanf("%lld%lld%lld",&a1,&b,&k);
                add(1,a1,b,k);
            } 
            else
            {
                scanf("%lld%lld",&a1,&b);
                printf("%lld
    ",ask(1,a1,b));
            }
         }
    
         return 0;
    }

    DO YOU LIKE MI FOR 爱

  • 相关阅读:
    关于ASPack 2.12加壳软件的脱壳方法[图文]
    OllyDbg快捷键记录帖
    C console编程
    用着VC++ Debug 理解汇编与C语言的对应关系
    赵青-《剑侠情缘网络版》开发回顾
    VC++ 预定义常量
    oracle分区自动创建
    清理oracle lobsegment
    libXext.so.6: cannot open shared object file: No such file or directory
    Oracle 杀死锁进程
  • 原文地址:https://www.cnblogs.com/ht008/p/6819853.html
Copyright © 2011-2022 走看看