zoukankan      html  css  js  c++  java
  • 模板

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

    首先是修改点:

    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;
    }
  • 相关阅读:
    Opensource .NET and Mono REST Web Services framework.NET Community Content on InfoQ Servicestack
    动态软件框架开发模型图
    数据库镜像
    DDD:策略模式如何结合动态表达式
    CentOS下j2ee环境搭建
    C#代码段编辑/编译工具
    .NET平台下不借助Office实现Word、Powerpoint等文件的解析(完)
    .NET Attribute(特性)的作用与用法
    tornado开发输入输出,数据库操作,内置模板,综合示例
    基于事件的异步编程模式(EMP)
  • 原文地址:https://www.cnblogs.com/Yinku/p/10473120.html
Copyright © 2011-2022 走看看