题目链接
题意:
给予\(n * n\)的矩阵,两种操作:
- \(x\) \(y\) \(d\),点\((x,y)\)的值增加d。
- \(x_1\) \(y_1\) \(x_2\) \(y_2\),查询矩阵\(x_1<=x<=x_2\),\(y_1<=y<=y_2\)内的元素和。
思路:
二维线段树,即线段树的每个节点内又有一个线段树,建树复杂度\(O(n^2)\),查询复杂度\(O(({logn})^2)\)。两种操作对应二维线段树单点更新,区间查询。
code:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <deque>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#define fi first
#define se second
#define pb push_back
#define endl "\n"
#define debug(x) cout << #x << ":" << x << endl;
#define bug cout << "********" << endl;
#define all(x) x.begin(), x.end()
#define lowbit(x) x & -x
#define fin(x) freopen(x, "r", stdin)
#define fout(x) freopen(x, "w", stdout)
#define ull unsigned long long
#define ll long long
const double eps = 1e-15;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const int mod = 1e9 + 7;
const int maxn = 1e3 + 10;
using namespace std;
#define lson rt << 1
#define rson rt << 1 | 1
ll t[maxn << 2][maxn << 2];
int n;
void rebuild(int rt, int l, int r, int num){
t[num][rt] = 0;
if(l == r)return ;
int mid = l + r >> 1;
rebuild(lson, l, mid, num), rebuild(rson, mid + 1, r, num);
}
void build(int rt, int l, int r){
rebuild(1, 1, n, rt);
if(l == r)return;
int mid = l + r >> 1;
build(lson, l, mid), build(rson, mid + 1, r);
}
void reupdate(int rt, int l, int r, int y, int num, int d){
if(l == r)return void(t[num][rt] += d);
int mid = l + r >> 1;
if(y <= mid)reupdate(lson, l, mid, y, num, d);
else reupdate(rson, mid + 1, r, y, num, d);
t[num][rt] = t[num][lson] + t[num][rson];
}
void update(int rt, int l, int r, int x, int y, int d){
reupdate(1, 1, n, y, rt, d);
if(l == r)return;
int mid = l + r >> 1;
if(x <= mid)update(lson, l, mid, x, y, d);
else update(rson, mid + 1, r, x, y, d);
}
ll requery(int rt, int l, int r, int Y1, int Y2, int num){
if(Y1 <= l && r <= Y2)return t[num][rt];
int mid = l + r >> 1;
ll ret = 0;
if(Y1 <= mid)ret += requery(lson, l, mid, Y1, Y2, num);
if(mid < Y2)ret += requery(rson, mid + 1, r, Y1, Y2, num);
return ret;
}
ll query(int rt, int l, int r, int X1, int Y1, int X2, int Y2){
if(X1 <= l && r <= X2)return requery(1, 1, n, Y1, Y2, rt);
int mid = l + r >> 1;
ll ret = 0;
if(X1 <= mid)ret += query(lson, l, mid, X1, Y1, X2, Y2);
if(mid < X2)ret += query(rson, mid + 1, r, X1, Y1, X2, Y2);
return ret;
}
int main(){
int a1, b1, a2, b2, t, y;
while(~scanf("%d", &t)){
if(t == 0)scanf("%d", &n), build(1, 1, n);
else if(t == 1){
scanf("%d%d%d", &a1, &b1, &y);
a1 ++, b1 ++;
update(1, 1, n, a1, b1, y);
}
else if(t == 2){
scanf("%d%d%d%d", &a1, &b1, &a2, &b2);
a1 ++, b1 ++, a2 ++, b2 ++;
ll ans = query(1, 1, n, a1, b1, a2, b2);
printf("%lld\n", ans);
}
else break;
}
return 0;
}