Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 18121 | Accepted: 8356 |
Description
Write a program, which receives these reports and answers queries about the current total number of active mobile phones in any rectangle-shaped area.
Input
The values will always be in range, so there is no need to check them. In particular, if A is negative, it can be assumed that it will not reduce the square value below zero. The indexing starts at 0, e.g. for a table of size 4 * 4, we have 0 <= X <= 3 and 0 <= Y <= 3.
Table size: 1 * 1 <= S * S <= 1024 * 1024
Cell value V at any time: 0 <= V <= 32767
Update amount: -32768 <= A <= 32767
No of instructions in input: 3 <= U <= 60002
Maximum number of phones in the whole table: M= 2^30
Output
Sample Input
0 4 1 1 2 3 2 0 0 2 2 1 1 1 2 1 1 2 -1 2 1 1 2 3 3
Sample Output
3 4
題意:
給定一個長寬爲S的矩陣,一開始裏面都是0,然後1對應操作是給(x , y)位置上的數增加多少,2對應的操作是查詢子矩陣的和爲多少。
題解:
二維樹狀數組可解。
#include <algorithm>
#include <iostream>
#include <numeric>
#include <cstring>
#include <iomanip>
#include <string>
#include <vector>
#include <cstdio>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const LL MAX = 405;
const double esp = 1e-6;
const double PI = 3.1415926535898;
const int INF = 0x3f3f3f3f;
using namespace std;
int arr[2048][2048];
int lowbit(int x){
return x&(-x);
}
void add(int x,int y,int val,int s){
for(int i=x;i<=s;i+=lowbit(i)){
for(int j=y;j<=s;j+=lowbit(j)){
arr[i][j] += val;
}
}
}
int query(int x,int y){
int ans = 0;
for(int i=x;i>0;i-=lowbit(i)){
for(int j=y;j>0;j-=lowbit(j)){
ans += arr[i][j];
}
}
return ans;
}
int main(){
int t,s,q,x,y,l,r;
while(~scanf("%d %d",&t,&s)){
memset(arr,false,sizeof(arr));
while(scanf("%d",&q) && q < 3){
if(q == 1){
scanf("%d %d %d",&x,&y,&l);
add(x+1,y+1,l,s);
}
else{
scanf("%d %d %d %d",&x,&y,&l,&r);
printf("%d\n",query(l+1,r+1)-query(l+1,y)-query(x,r+1)+query(x,y));
}
}
}
return 0;
}