問題 G: 矩陣(二維樹狀數組)

題目鏈接:問題 G: 矩陣

這裏寫圖片描述
輸入
這裏寫圖片描述
輸出
這裏寫圖片描述
樣例輸入
1
3 4 4
Q 1 1 1 1
Q 1 1 3 2
M 1 1 3
Q 1 1 3 4
樣例輸出
2
21
55

提示
這裏寫圖片描述

思路:
二維樹狀數組求解矩陣的區間和,和單點更新。

樹狀數組的講解:傳送門

代碼:

#include <stdio.h>
#include <string.h>
#include <algorithm>
typedef long long ll;
const int maxn=1009;
using namespace std;
int n,m,num[maxn][maxn],t,q;
ll tree[maxn][maxn];
char str[3];
int lowbit(int t)
{
    return t&(-t);
}
void add_num(int x,int y,ll val)//處理求解矩陣的區間和
{
    if(x==0||y==0) return;
    for(int i=x; i<=n; i+=(lowbit(i)))
        for(int j=y; j<=m; j+=lowbit(j))
            tree[i][j]+=val;
}
ll tree_sum(int x,int y)//查找(1,1)到(x,y)的區間和
{
    ll ans=0;
    for(int i=x; i>=1; i-=lowbit(i))
        for(int j=y; j>=1; j-=lowbit(j))
            ans+=tree[i][j];
    return ans;
}
int main()
{
    int x1,y1,x2,y2,tem;
    ll val;
    scanf("%d",&t);
    while(t--)
    {
        memset(tree,0,sizeof(tree));
        scanf("%d%d%d",&n,&m,&q);
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                num[i][j]=i+j;
            }
        }
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
                add_num(i,j,num[i][j]);
        }
        for(int i=1; i<=q; i++)
        {
            scanf("%s",str);
            if(str[0]=='Q')
            {
                scanf("%d%d%d%d",&x2,&y2,&x1,&y1);
                printf("%lld\n",tree_sum(x1,y1)-tree_sum(x1,y2-1)-tree_sum(x2-1,y1)+tree_sum(x2-1,y2-1));
            }
            else
            {
                scanf("%d%d%lld",&x1,&y1,&val);
                tem=val;
                val-=num[x1][y1];
                num[x1][y1]=tem;
                add_num(x1,y1,val);
            }
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章