POJ 1195 Mobile phones (树状数组)
题意:给定n*n矩阵,和几种在线操作,包括对某一点(x,y)值修改,查询一个矩形(x1,y1,x2,y2)的元素和。
思路:典型的在线查询,可用树状数组实现,查询矩形和时,稍微注意以下就可以了:
sum(x2,y2)+sum(x1-1,y1-1)-sum(x1-1,y2)-sum(x2,y1-1);
还要注意树状数组的修改操作modify(index,delta)中的index要>0。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <memory.h>
#include <cmath>
#include <bitset>
#include <queue>
#include <vector>
using namespace std;
const int BORDER = (1<<20)-1;
const int MAXSIZE = 37;
const int MAXN = 1100;
const int INF = 1000000000;
#define CLR(x,y) memset(x,y,sizeof(x))
#define ADD(x) x=((x+1)&BORDER)
#define IN(x) scanf("%d",&x)
#define OUT(x) printf("%d\n",x)
#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) ((x)>0?(x):-(x))
int tre[MAXN][MAXN];
int n,n_tre,t_case;
int lowbit(int x)
{
return x&(-x);
}
void modify(const int& x,const int& y,const int delta)
{
for(int i = x; i <= n_tre; i += lowbit(i))
for(int j = y; j <= n_tre; j += lowbit(j))
{
tre[i][j] += delta;
}
}
int get_sum(const int& x,const int& y)
{
int sum = 0;
for(int i = x; i > 0; i -= lowbit(i))
for(int j = y; j > 0; j -= lowbit(j))
sum += tre[i][j];
return sum;
}
int init()
{
CLR(tre,0);
return 0;
}
int work()
{
int i,j,x1,x2,y1,y2,x,y,val,tmp,ans;
char s[3];
n_tre = n+5;
while(scanf("%s",s))
{
if(s[0] == '3')
break;
if(s[0] == '1')
{
scanf("%d%d%d",&x,&y,&val);
modify(x+1,y+1,val);
}else
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
ans = get_sum(x2+1,y2+1)+get_sum(x1,y1)-
get_sum(x1,y2+1)-get_sum(x2+1,y1);
OUT(ans);
}
}
return 0;
}
int main()
{
while(scanf("%d %d",&t_case,&n)!=EOF)
{
init();
work();
}
return 0;
}