题目链接:点击打开链接
题意:给定n*m的二维平面 w个操作
int mp[n][m] = { 0 };
1、0 (x1,y1) (x2,y2) value
for i : x1 to x2
for j : y1 to y2
mp[i][j] += value;
2、1 (x1, y1) (x2 y2)
ans1 = 纵坐标在 y1,y2间的总数
ans2 = 横坐标不在x1,x2间的总数
puts(ans1-ans2);
more format:
for i : 1 to n
for j : y1 to y2
ans1 += mp[i][j]
因为n最大是4e6, 所以用树状数组改段求段代替线段树
#include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> template <class T> inline bool rd(T &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; while (c != '-' && (c<'0' || c>'9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } template <class T> inline void pt(T x) { if (x <0) { putchar('-'); x = -x; } if (x>9) pt(x / 10); putchar(x % 10 + '0'); } using namespace std; typedef long long ll; const int N = 4e6 + 100; template<class T> struct Tree{ T c[2][N]; int maxn; void init(int x){ maxn = x+10; memset(c, 0, sizeof c); } inline int lowbit(int x){ return x&-x; } T sum(T *b, int x){ T ans = 0; if (x == 0)ans = b[0]; while (x)ans += b[x], x -= lowbit(x); return ans; } void change(T *b, int x, T value){ if (x == 0)b[x] += value, x++; while (x <= maxn)b[x] += value, x += lowbit(x); } T get_pre(int r){ return sum(c[0], r) * r + sum(c[1], r); } void add(int l, int r, T value){ change(c[0], l, value); change(c[0], r + 1, -value); change(c[1], l, value * (-l + 1)); change(c[1], r + 1, value * r); } T get(int l, int r){ return get_pre(r) - get_pre(l - 1); } }; Tree<ll> x, y; int main(){ int n, m, w; rd(n); rd(m); rd(w); x.init(n); y.init(m); ll all = 0; while (w--){ int op, x1, x2, y1, y2; ll value; rd(op); rd(x1); rd(y1); rd(x2); rd(y2); if (op == 0) { rd(value); all += value * (x2 - x1 + 1) * (y2 - y1 + 1); x.add(x1, x2, value * (y2 - y1 + 1)); y.add(y1, y2, value * (x2 - x1 + 1)); } else { pt(y.get(1, y2) - y.get(1, y1 - 1) - (all - x.get(1, x2) + x.get(1, x1 - 1))); puts(""); } } return 0; }