• 一维数状数组区间修改,查询


    模板题CODEVS-1082

    给你N个数,有两种操作:

    1:给区间[a,b]的所有数增加X

    2:询问区间[a,b]的数的和。             

    第一行一个正整数n,接下来n行n个整数,

    再接下来一个正整数Q,每行表示操作的个数,

    如果第一个数是1,后接3个正整数,

    表示在区间[a,b]内每个数增加X,如果是2,

    表示操作2询问区间[a,b]的和是多少。

    一维树状数组可以考虑用差分来做,但是扩展不到二维。

    所以我们令di=(ai~an)的增量

    思路和差分一样

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    #define lowbit(x) x&(-x)
    int n,m,a[1000005],c1[1000005],c2[1000005];
    void update(int v,int val)
    {
        for(int pp=v;pp<=n;c1[pp]+=val,c2[pp]+=val*v,pp+=lowbit(pp));
    }
    int query(int l,int r)
    {
        int ans=0;
        for(int pp=r;pp>0;ans+=(r+1)*c1[pp],ans-=c2[pp],pp-=lowbit(pp));
        l--;
        for(int pp=l;pp>0;ans-=(l+1)*c1[pp],ans+=c2[pp],pp-=lowbit(pp));
        return ans;
    }
    int main()
    {
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
        update(i,a[i]-a[i-1]);
        
        for(int i=1;i<=m;i++)
        {
            int p,l,r,val;
            scanf("%d %d %d",&p,&l,&r);
            if(p==1)
            {
                scanf("%d",&val);
                update(l,val);
                update(r+1,-val);
            }else
            {
                printf("%d
    ",query(l,r));
            }
        }
                
        return 0;
    }
  • 相关阅读:
    项目架构开发:数据访问层之Cache
    微信公众号平台接口开发:菜单管理
    【软件工程】第0次个人作业
    OO第四次博客作业
    OO第三次博客作业
    OO第二次博客作业
    Java学习笔记
    SQLInjection 靶场配置
    OO第一次博客作业
    面向对象先修:Java入门
  • 原文地址:https://www.cnblogs.com/dancer16/p/6882430.html
Copyright © 2020-2023  润新知