poj 3468 A Simple Problem with Integers 【區間修改+區間查詢(樹狀陣列)】
阿新 • • 發佈:2018-12-22
參考下面部落格的公式:
需要注意的是,輸入初始數列的時候要 add 兩次, L = R, add (L, x), add (R+1, -x)
#include <iostream> #include <cstring> #include <cstdio> using namespace std; typedef long long ll; const int Maxn = 1e5+10; ll d[Maxn],di[Maxn]; int n; void add (int x, int y) { int tmp = x; while (x <= n) { d[x] += y; di[x] += (ll)tmp*y; x += x&(-x); } } ll sum (int x) { ll ret = 0, ans2 = 0; int tmp = x; while (x > 0) { ret+= (tmp+1)*d[x]-di[x]; x -= x&(-x); } return ret; } int main (void) { int m, tmp; scanf ("%d%d", &n, &m); for (int i = 1; i <= n; ++i) { scanf ("%d", &tmp); add (i, tmp); // 注意輸入初始值的時候需要 add兩次, add (i+1, -tmp); // L = R = i,add (L, x),add (R+1, -x) } char op[2]; int L, R, val; while (m--) { scanf ("%s", op); if (!strcmp (op, "C")) { scanf ("%d%d%d", &L, &R, &val); add (L, val); add (R+1, -val); } else { scanf ("%d%d", &L, &R); printf ("%lld\n", sum (R)-sum(L-1)); } } return 0; }