这题可以用线段树离散化做,用二维树状数组做了一下,不懂得可以看一下这篇文章:http://www.java3z.com/cwbwebhome/article/article1/1369.html?id=4804
题意:
给你一个s*s的正方形区域,先输入一个x,若x==0,则再输入一个s,若x==1,则输入x,y,a,表示矩阵中(x,y)这点的值加上a,若x==2,输入l,b,r,t,代表以左上角的点(l,b)右下角的点(r,t),求这一片矩形内的矩阵元素之和,若x==3则结束此次程序
就是最基础的二维树状数组的应用,修改单点的值,并且快速求区间和
#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
#include<cctype>
#define ll long long
#define LL __int64
#define eps 1e-8
//const ll INF=9999999999999;
#define inf 0xfffffff
using namespace std;
//vector<pair<int,int> > G;
//typedef pair<int,int> P;
//vector<pair<int,int>> ::iterator iter;
//
//map<ll,int>mp;
//map<ll,int>::iterator p;
int n;
int c[1000 + 35][1000 + 35];
void clear() {
memset(c,0,sizeof(c));
}
int lowbit(int x) {
return x&(-x);
}
void add(int x,int y,int value) {
int i = y;
while(x <= n) {
y = i;
while(y <= n) {
c[x][y] += value;
y += lowbit(y);
}
x += lowbit(x);
}
}
int get_sum(int x,int y) {
int sum=0,i = y;
while(x > 0) {
y = i;
while(y > 0) {
sum += c[x][y];
y -= lowbit(y);
}
x -= lowbit(x);
}
return sum;
}
int main() {
int x;
while(true) {
scanf("%d",&x);
if(x == 0) {
scanf("%d",&n);
n++;
clear();
}
else if(x == 1) {
int x,y,a;
scanf("%d %d %d",&x,&y,&a);
add(++x,++y,a);//矩阵行列标由0开始要处理掉
}
else if(x == 2) {
int l,b,r,t;
scanf("%d %d %d %d",&l,&b,&r,&t);
l++,b++,r++,t++;//处理行列标
int ans = 0;
//int a1 = get_sum(r,b-1);
//int a2 = get_sum(l-1,b-1);
//int a3 = get_sum(r,t);
//int a4 = get_sum(l-1,t);
ans = get_sum(r,t) - get_sum(l-1,t) - get_sum(r,b-1) + get_sum(l-1,b-1);
printf("%d\n",ans);
}
else break;
}
return 0;
}