Problem 3 二維差分
阿新 • • 發佈:2018-10-10
操作 for 就是 三角形 namespace swe 給定 sin std
$des$
考慮一個 n ∗ n 的矩陣 A,初始所有元素均為 0。
執行 q 次如下形式的操作: 給定 4 個整數 r,c,l,s, 對於每個滿足 x ∈ [r,r+l), y ∈ [c,x−r+c]
的元素 (x,y),將權值增加 s。也就是,給一個左上頂點為 (r,c)、直角邊長為 l 的下三角區域加
上 s。
輸出最終矩陣的元素異或和。
$sol$
每次加減是一個等腰直角三角形
考慮對每行查分
即對垂直於 x 軸的腰上的每個點 +1 ,所有斜邊的後一個點 -1
這樣的話,每行形成了查分數組
簡化上面的過程
對腰上的點 +1 時同樣也可以查分進行
對斜邊上的點同理,只不過還原時 $a_{i, j} += a_{i - 1, j - 1}$
註意判斷邊界條件
$code$
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <string> #include <cstdlib> using namespace std; const int N = 2010; #definegc getchar() inline int read() { int x = 0; char c = gc; while(c < ‘0‘ || c > ‘9‘) c = gc; while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘, c = gc; return x; } #undef gc #define Rep(i, a, b) for(int i = a; i <= b; i ++) #define LL long long LL add[N][N], cut[N][N];struct Node { int r, c, l, s; } Ask[(int)3e5 + 10]; int n, q; LL A[N][N], B[N][N]; int main() { n = read(), q = read(); Rep(qq, 1, q) Ask[qq] = (Node) { read(), read(), read(), read() }; Rep(i, 1, q) { int r = Ask[i].r, c = Ask[i].c, l = Ask[i].l, s = Ask[i].s; add[r][c] += s; add[r + l][c] -= s; cut[r][c + 1] += s; cut[r + l][c + l + 1] -= s; } Rep(j, 1, n) { Rep(i, 1, n) add[i][j] += add[i - 1][j]; } Rep(i, 1, n) { Rep(j, 1, n) cut[i][j] += cut[i - 1][j - 1]; } Rep(i, 1, n) { Rep(j, 1, n) A[i][j] += A[i][j - 1] + add[i][j] - cut[i][j]; } LL Answer = 0; Rep(i, 1, n) Rep(j, 1, n) Answer ^= A[i][j]; cout << Answer; return 0; }
Problem 3 二維差分