題目鏈接:問題 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;
}