Advertisement
kartikkukreja

Range Updates/Range Queries with BIT

Dec 2nd, 2013
334
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.69 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstring>
  3. #define LSOne(S) (S & (-S))
  4. using namespace std;
  5.  
  6. typedef long long ll;
  7.  
  8. // B1 and B2 are two fenwick trees
  9. // Original array entries are assumed to be 0
  10. // and only updates are stored.
  11. ll B1[100005], B2[100005];
  12.  
  13. // Array size
  14. int N;
  15.  
  16. // Point query
  17. // Returns value at position b in the array for ft = B1
  18. // Returns value to be subtracted from query(B1, b) * b for ft = B2
  19. ll query(ll* ft, int b) {
  20.     ll sum = 0;
  21.     for (; b; b -= LSOne(b)) sum += ft[b];
  22.     return sum;
  23. }
  24.  
  25. // Range query: Returns the sum of all elements in [1...b]
  26. ll query(int b) {
  27.     return query(B1, b) * b - query(B2, b);
  28. }
  29.  
  30. // Range query: Returns the sum of all elements in [i...j]
  31. ll range_query(int i, int j)    {
  32.     return query(j) - query(i - 1);
  33. }
  34.  
  35. // Point update: Adds v to the value at position k in the array
  36. // ft is the fenwick tree which represents that array
  37. void update(ll* ft, int k, ll v) {
  38.     for (; k <= N; k += LSOne(k)) ft[k] += v;
  39. }
  40.  
  41. // Range update: Adds v to each element in [i...j]
  42. void range_update(int i, int j, ll v)   {
  43.     update(B1, i, v);
  44.     update(B1, j + 1, -v);
  45.     update(B2, i, v * (i - 1));
  46.     update(B2, j + 1, -v * j);
  47. }
  48.  
  49. int main()  {
  50.     int T, C, p, q, cmd;
  51.     ll v;
  52.  
  53.     scanf("%d", &T);
  54.     while (T--) {
  55.         // C -> No. of operations
  56.         scanf("%d %d", &N, &C);
  57.         memset(B1, 0, (N+1) * sizeof(ll));
  58.         memset(B2, 0, (N+1) * sizeof(ll));
  59.         while (C--) {
  60.             scanf("%d %d %d", &cmd, &p, &q);
  61.             // cmd is 0 for a range update and 1 for a range query
  62.             if (cmd == 0)   {
  63.                         scanf("%lld", &v);
  64.                         range_update(p, q, v);
  65.             } else
  66.                         printf("%lld\n", range_query(p, q));
  67.         }
  68.     }
  69.  
  70.     return 0;
  71. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement