P3368【模板】樹狀數組 2 - 差分
阿新 • • 發佈:2018-10-14
can names 表示 name sum else display \n 增量
建立兩個差分數組,套公式就好了
c[i]表示i元素的“增量”,下面的式子左邊是序列從1 ~ x的前綴和整體增加的值
\[\sum_{i=1}^x\sum_{j=1}^ic[j] = (x+1)\sum_{i=1}^xc[i] - \sum_{i=1}^xi*c[i] \]
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; #define debug(x) cerr << #x << "=" << x << endl; const int MAXN = 500000 + 10; int n,m,tr[MAXN],c1[MAXN],c2[MAXN],sum[MAXN]; void update(int k, int p, int c[]) { while(p <= n) { c[p] += k; p += p&(-p); } } int getsum(int p, int c[]) { int sum = 0; while(p) { sum += c[p]; p -= p&(-p); } return sum; } int main() { scanf("%d%d", &n, &m); for(int i=1; i<=n; i++) { int ai = 0; scanf("%d", &ai); sum[i] = sum[i-1] + ai; } for(int i=1; i<=m; i++) { int cmd, x, y, k; scanf("%d", &cmd); if(cmd == 1) { scanf("%d%d%d", &x, &y, &k); update(k, x, c1), update(-k, y+1, c1); update(k*x, x, c2), update(-k * (y+1), y+1, c2); } else { scanf("%d", &x); int ls = sum[x-1] + x * getsum(x-1, c1) - getsum(x-1, c2); int rs = sum[x] + (x+1) * getsum(x, c1) - getsum(x, c2); printf("%d\n", rs - ls); } } return 0; }
P3368【模板】樹狀數組 2 - 差分