欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

二维树状数组 :单点修改,区间查询(模板)

程序员文章站 2024-03-03 17:53:28
...

题目传送门

给你一个n*m的邻接矩阵,完成以下两个操作。

"1 x y k":表示元素 Ax,y 自增 k;
"2 a b c d":表示询问左上角为 (a,b),右下角为 (c,d) 的子矩阵内所有数的和。

input

输入的第一行有两个正整数 n,m;

接下来若干行,每行一个操作,直到文件结束。

output

对于每个 "2" 操作,输出一个整数,表示对于这个操作的回答。

example

Input
2 2
1 1 1 3
1 2 2 4
2 1 1 2 2
Output
7

note

1≤n,m≤2^12,1≤x,a,c≤n,1≤y,b,d≤m,|k|105,保证操作数目不超过 3×10^5,且询问的子矩阵存在。

基本操作和一维树状数组差不多,求和的时候注意下二维前缀和的求法就可以。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e3+5;
const int mod=1e9+7;
const int INF=0x7fffffff;
const ll LLINF=0x7fffffffffffffff;
const double EPS=1e-10;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define debug cout<<"debug"<<endl;
#define ls p<<1
#define rs p<<1|1
#define int long long
int c[N][N];
int lowbit(int x)
{
    return x&-x;
}
int n,m;
void add(int x,int y,int k)
{
    for(int i=x;i<=n;i+=lowbit(i))
    {
        for(int j=y;j<=m;j+=lowbit(j))
        {
            c[i][j]+=k;
        }
    }
}
int sum(int x,int y)
{
    int s=0;
    for(int i=x;i;i-=lowbit(i))
    {
        for(int j=y;j;j-=lowbit(j))
        {
            s+=c[i][j];
        }
    }
    return s;
}
signed main()
{
    IOS;
    //freopen("","r",stdin);
    //freopen("","w",stdout);
    scanf("%lld%lld",&n,&m);
    int oo,x,y,z,w;
    while(scanf("%lld",&oo)!=EOF)
    {
        if(oo==1)
        {
            scanf("%lld%lld%lld",&x,&y,&z);
            add(x,y,z);
        }
        else
        {
            scanf("%lld%lld%lld%lld",&x,&y,&z,&w);
            printf("%lld\n",sum(z,w)-sum(x-1,w)-sum(z,y-1)+sum(x-1,y-1));
        }
    }
}
相关标签: 数据结构