fork download
  1. #include <bits/stdc++.h>
  2. using namespace std ;
  3.  
  4. class SegmentTree {
  5. private:
  6. int n ;
  7. vector<int> seg ;
  8. vector<int> lazy ;
  9.  
  10. public:
  11. SegmentTree(int n) {
  12. this -> n = n ;
  13. seg.resize((n << 2) + 1 , 0) ;
  14. lazy.resize((n << 2) + 1 , 0) ;
  15. }
  16.  
  17. void build(int ind , int low , int high , vector<int>& arr) {
  18. if(low == high) {
  19. seg[ind] = arr[low] ;
  20. return ;
  21. }
  22.  
  23. int mid = low + ((high - low) / 2) ;
  24. build((ind << 1) + 1 , low , mid , arr) ;
  25. build((ind << 1) + 2 , mid + 1 , high , arr) ;
  26. seg[ind] = seg[(ind << 1) + 1] + seg[(ind << 1) + 2] ;
  27. }
  28.  
  29. int query(int ind , int qsi , int qei , int low , int high) {
  30. if (lazy[ind] != 0) {
  31. seg[ind] += (high - low + 1) * lazy[ind];
  32.  
  33. if (low != high) {
  34. lazy[(ind << 1) + 1] += lazy[ind];
  35. lazy[(ind << 1) + 2] += lazy[ind];
  36. }
  37.  
  38. lazy[ind] = 0;
  39. }
  40.  
  41. // Case-1: No Overlap
  42. if(high < qsi || low > qei) {
  43. return 0 ;
  44. }
  45.  
  46. // Case-2: Complete Overlap
  47. if(low >= qsi && high <= qei) {
  48. return seg[ind] ;
  49. }
  50.  
  51. // Case-3: Partial Overlap
  52. int mid = low + ((high - low) / 2) ;
  53. int left = query((ind << 1) + 1 , qsi , qei , low , mid) ;
  54. int right = query((ind << 1) + 2 , qsi , qei , mid + 1 , high) ;
  55. return left + right ;
  56. }
  57.  
  58. int query(int qsi , int qei) {
  59. return query(0 , qsi , qei , 0 , n - 1) ;
  60. }
  61.  
  62. void pointUpdate(int updateInd , int val) {
  63. int curr = query(updateInd , updateInd) ;
  64. rangeUpdate(updateInd , updateInd , val - curr) ;
  65. }
  66.  
  67. void rangeUpdate(int ind , int rangeLeft , int rangeRight , int inc , int low , int high) {
  68. // Update pending update if we visit the node think greedily that if we are visiting the node then update it naa in O(1) time so that in future we don't want to come specially to update it
  69. if(lazy[ind] != 0) {
  70. seg[ind] += (high - low + 1) * lazy[ind] ;
  71.  
  72. // Propogate the updates down
  73. if (low != high) {
  74. lazy[(ind << 1) + 1] += lazy[ind];
  75. lazy[(ind << 1) + 2] += lazy[ind];
  76. }
  77.  
  78. lazy[ind] = 0 ;
  79. }
  80.  
  81. if(high < rangeLeft || low > rangeRight) {
  82. return ;
  83. }
  84.  
  85. if(low >= rangeLeft && high <= rangeRight) {
  86. seg[ind] += (high - low + 1) * inc ;
  87.  
  88. if(low != high) {
  89. lazy[(ind << 1) + 1] += inc ;
  90. lazy[(ind << 1) + 2] += inc ;
  91. }
  92. return ;
  93. }
  94.  
  95. int mid = low + ((high - low) / 2) ;
  96. rangeUpdate((ind << 1) + 1 , rangeLeft , rangeRight , inc , low , mid) ;
  97. rangeUpdate((ind << 1) + 2 , rangeLeft , rangeRight , inc , mid + 1 , high) ;
  98. seg[ind] = seg[(ind << 1) + 1] + seg[(ind << 1) + 2] ;
  99. }
  100.  
  101. void rangeUpdate(int rangeLeft , int rangeRight , int inc) {
  102. rangeUpdate(0 , rangeLeft , rangeRight , inc , 0 , n - 1) ;
  103. }
  104. };
  105.  
  106. void solve() {
  107. int n ; cin >> n ;
  108. vector<int> arr(n) ;
  109. for(int i = 0 ; i < n ; i++) {
  110. cin >> arr[i] ;
  111. }
  112. SegmentTree st(n) ;
  113. st.build(0 , 0 , n - 1 , arr) ;
  114.  
  115. int q ; cin >> q ;
  116. for(int Q = 0 ; Q < q ; Q++) {
  117. int type ; cin >> type ;
  118.  
  119. // Type-1: Query
  120. if(type == 1) {
  121. int l , r ; cin >> l >> r ;
  122. cout << st.query(l , r) << endl ;
  123. }
  124. // Type-2: Point Update
  125. else if(type == 2) {
  126. int ind , val ; cin >> ind >> val ;
  127. st.pointUpdate(ind , val) ;
  128. }
  129. // Type-3: Range Update
  130. else if(type == 3) {
  131. int l , r , inc ; cin >> l >> r >> inc ;
  132. st.rangeUpdate(l , r , inc) ;
  133. }
  134. }
  135. }
  136.  
  137. int main() {
  138.  
  139. // freopen("input.txt" , "r" , stdin) ;
  140. // freopen("output.txt" , "w" , stdout) ;
  141.  
  142. int t ; cin >> t ;
  143. while(t--) {
  144. solve() ;
  145. }
  146. return 0 ;
  147. }
Success #stdin #stdout 0s 5312KB
stdin
1
5
1 3 1 2 5
5
1 0 4
3 0 4 2
1 0 4
2 2 10
1 0 4
stdout
12
22
29