• 模板


    二维树状数组涉及到两种基本操作,修改矩阵中的一个点,查询子矩阵的和。

    首先是修改点:

    void update(int x,int y,int z)
    {
        for(int i=x;i<=n;i+=lowbit(i))
        for(int j=y;j<=m;j+=lowbit(j))
            c[i][j]+=z;
    }

    然后是查询前缀和:

    int get_sum(int x,int y)
    {
        int ret=0;
        for(int i=x;i>=1;i-=lowbit(i))
        for(int j=y;j>=1;j-=lowbit(j))
            ret+=c[i][j];
        return ret;
    }

    那么由容斥原理:

    inline int query(int x1,int y1,int x2,int y2){
        return get_sum(x2,y2)-get_sum(x1-1,y2)-get_sum(x2,y1-1)+get_sum(x1-1,y1-1);
    }

    区间修改就麻烦一点:

    方法1:

    #include<iostream>
    using namespace std;
    const int maxn=1005;
    const int maxm=1005;
    int n,m;
    int q;
    int a[maxn][maxm];
    int c[maxn][maxm];
    int lowbit(int x)
    {
        return x&(-x);
    }
    void update(int x,int y,int z)
    {
        for(int i=x;i<=n;i+=lowbit(i))
        for(int j=y;j<=m;j+=lowbit(j))
            c[i][j]+=z;
    }
    
    int sum(int x,int y)
    {
        int ret=0;
        for(int i=x;i>=1;i-=lowbit(i))
        for(int j=y;j>=1;j-=lowbit(j))
            ret+=c[i][j];
        return ret;
    }
    int main()
    {
        cin>>n>>m;
        cin>>q;
        while(q--)
        {
            int x;
            cin>>x;
            if(x==1)
            {
                int x1,y1,x2,y2,w;
                cin>>x1>>y1>>x2>>y2>>w;
                update(x1,y1,w);
                update(x2+1,y2+1,w);
                update(x2+1,y1,-w);
                update(x1,y2+1,-w);
            }
            if(x==2)
            {
                int x,y;
                cin>>x>>y;
                cout<<sum(x,y)<<endl;
            }
        }
        return 0;
    }

    方法2:

    #include<iostream>
    using namespace std;
    const int maxn=1005;
    const int maxm=1005;
    int n,m;
    int q;
    int a[maxn][maxm];
    int c1[maxn][maxm];
    int c2[maxn][maxm];
    int c3[maxn][maxm];
    int c4[maxn][maxm];
    int lowbit(int x)
    {
        return x&(-x);
    }
    void update(int c[][maxm],int x,int y,int z)
    {
        for(int i=x;i<=n;i+=lowbit(i))
        for(int j=y;j<=m;j+=lowbit(j))
            c[i][j]+=z;
    }
    
    int sum(int c[][maxm],int x,int y)
    {
        int ret=0;
        for(int i=x;i>=1;i-=lowbit(i))
        for(int j=y;j>=1;j-=lowbit(j))
            ret+=c[i][j];
        return ret;
    }
    
    int get(int x,int y)
    {
        return sum(c1,x,y)*(x+1)*(y+1)-sum(c2,x,y)*(y+1)-(x+1)*sum(c3,x,y)+sum(c4,x,y);
    }
    int main()
    {
        cin>>n>>m;
        cin>>q;
        while(q--)
        {
            int x;
            cin>>x;
            if(x==1)
            {
                int x1,y1,x2,y2,w;
                cin>>x1>>y1>>x2>>y2>>w;
                update(c1,x1,y1,w),update(c1,x1,y2+1,-w);
                update(c1,x2+1,y1,-w),update(c1,x2+1,y2+1,w);
            
                update(c2,x1,y1,w*x1),update(c2,x2+1,y1,-w*(x2+1));
                update(c2,x1,y2+1,-w*x1),update(c2,x2+1,y2+1,w*(x2+1));
            
                update(c3,x1,y1,w*y1),update(c3,x2+1,y1,-w*y1);
                update(c3,x1,y2+1,-w*(y2+1)),update(c3,x2+1,y2+1,w*(y2+1));
            
                update(c4,x1,y1,w*x1*y1),update(c4,x2+1,y1,-w*(x2+1)*y1);
                update(c4,x1,y2+1,-w*x1*(y2+1)),update(c4,x2+1,y2+1,w*(x2+1)*(y2+1));
            }
            if(x==2)
            {
                int x1,y1,x2,y2;
                cin>>x1>>y1>>x2>>y2;
                cout<<get(x2,y2)-get(x2,y1-1)-get(x1-1,y2)+get(x1-1,y1-1)<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    判断的几种结构
    关于电脑的基础单词笔记
    JAVA插入数据笔记
    完全卸载oracle11g步骤
    hibernate框架
    Java中的字符串比较
    java集合 list与Set、Map区别
    向MyEclipse的项目中导入js文件时,出现小红叉
    Java基础面试题
    java面试题 -- JVM
  • 原文地址:https://www.cnblogs.com/Yinku/p/10473120.html
Copyright © 2020-2023  润新知