【POJ 3468】 A Simple Problem with Integers
【题目链接】
【算法】
本题用线段树很容易写,但是,笔者为了练习树状数组,就用树状数组的方法做了一遍
我们不妨引入差分数组c,
则sum(n) = c[1] + (c[1] + c[2]) + (c[1] + c[2] + c[3]) + ... + (c[1] + c[2] + c[3] + ... + c[n])
= n * c[1] + (n - 1) * c[2] + (n - 2) * c[3] + ... + c[n]
= n * (c[1] + c[2] + c[3] + ... + c[n]) - c[2] - c[3] * 2 - c[4] * 3 - ... - c[n] * (n - 1)
所以可以用两个树状数组分别维护c的前缀和和c[i]*(i-1)的前缀和
【代码】
#include <algorithm> #include <bitset> #include <cctype> #include <cerrno> #include <clocale> #include <cmath> #include <complex> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque> #include <exception> #include <fstream> #include <functional> #include <limits> #include <list> #include <map> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stdexcept> #include <streambuf> #include <string> #include <utility> #include <vector> #include <cwchar> #include <cwctype> #include <stack> #include <limits.h> using namespace std; #define MAXN 100000 long long N,Q,tr,tl,i,l,r,x; long long a[MAXN+10]; char opt; template <typename T> inline void read(T &x) { long long f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; } for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } template <typename T> inline void write(T x) { if (x < 0) { x = -x; putchar('-'); } if (x > 9) write(x/10); putchar(x%10+'0'); } template <typename T> inline void writeln(T x) { write(x); puts(""); } struct BinaryIndexedTree { long long bit[MAXN+10]; inline long long lowbit(long long x) { return x & -x; } inline void clear() { long long i; for (i = 1; i <= N; i++) bit[i] = 0; } inline void modify(long long pos,long long val) { long long i; for (i = pos; i <= N; i += lowbit(i)) bit[i] += val; } inline long long query(long long pos) { long long i,ret = 0; for (i = pos; i; i -= lowbit(i)) ret += bit[i]; return ret; } } c1,c2; int main() { read(N); read(Q); for (i = 1; i <= N; i++) { read(a[i]); c1.modify(i,a[i]); c1.modify(i+1,-a[i]); c2.modify(i,(i-1)*a[i]); c2.modify(i+1,-i*a[i]); } while (Q--) { opt = getchar(); if (opt == 'C') { read(l); read(r); read(x); c1.modify(l,x); c1.modify(r+1,-x); c2.modify(l,(l-1)*x); c2.modify(r+1,-x*r); } else { read(l); read(r); tl = c1.query(l-1) * (l - 1) - c2.query(l-1); tr = c1.query(r) * r - c2.query(r); writeln(tr-tl); } } return 0; } /* c[1] + (c[1] + c[2]) + (c[1] + c[2] + c[3]) + ... + (c[1] + c[2] + c[3] + c[4] + ... + c[n]) = c[1] * n + c[2] * (n - 1) + c[3] * (n - 2) + ... + c[n] = (c[1] + c[2] + c[3] + ... + c[n]) * n - c[2] - c[3] * 2 - c[4] * 3 - ... - c[n] * (n - 1) = sigma(c1,n) * n - sigma(c2,n) */