Queries to calculate sum of squares of array elements over range of indices [L, R] with updates

  
#include
using namespace std;
  

vector seg(400000, 0),
    dseg(400000, 0),
    a(100000);
  

vector segSum(400000, 0);
  

void build(int ind, int low, int high)
{
    
    if (low == high) {
  
        
        seg[ind] = a[low] * a[low];
        segSum[ind] = a[low];
        return;
    }
  
    
    int mid = (low + high) / 2;
  
    
    
    build(2 * ind + 1, low, mid);
    build(2 * ind + 2, mid + 1, high);
  
    
    seg[ind] = seg[2 * ind + 1]
               + seg[2 * ind + 2];
  
    
    segSum[ind] = segSum[2 * ind + 1]
                  + segSum[2 * ind + 2];
}
  

long long rangesum(int ind, int low,
                   int high, int l,
                   int r)
{
    
    if (dseg[ind] != 0) {
  
        
        
        seg[ind] += (high – low + 1)
                        * dseg[ind]
                        * dseg[ind]
                    + (2 * dseg[ind]
                       * segSum[ind]);
  
        
        
        segSum[ind] += (high – low + 1)
                       * dseg[ind];
  
        
        if (low != high) {
            dseg[2 * ind + 1] += dseg[ind];
            dseg[2 * ind + 2] += dseg[ind];
        }
        dseg[ind] = 0;
    }
  
    
    if (r < low || l > high
        || low > high) {
        return 0;
    }
  
    
    if (l = high) {
        return seg[ind];
    }
  
    
    int mid = (low + high) / 2;
  
    
    return rangesum(2 * ind + 1,
                    low, mid, l, r)
           + rangesum(2 * ind + 2,
                      mid + 1, high,
                      l, r);
}
  

void rangeQuery(int ind, int low,
                int high, int l, int r,
                int update, int type)
{
    
    if (dseg[ind] != 0) {
  
        
        seg[ind]
            += (high – low + 1)
               * dseg[ind] * dseg[ind];
  
        
        segSum[ind] += (high – low + 1)
                       * dseg[ind];
  
        if (low != high) {
            dseg[2 * ind + 1] += dseg[ind];
            dseg[2 * ind + 2] += dseg[ind];
        }
  
        dseg[ind] = 0;
    }
  
    
    if (r < low || l > high
        || low > high) {
        return;
    }
  
    
    if (l = high) {
  
        
        if (type == 1) {
  
            
            
            seg[ind] = (high – low + 1)
                       * update * update;
  
            
            
            segSum[ind] = (high – low + 1)
                          * update;
        }
        else {
  
            
            
            seg[ind] += (high – low + 1)
                            * update * update
                        + 2 * update
                              * segSum[ind];
  
            
            
            segSum[ind] += (high – low + 1)
                           * update;
        }
  
        
        if (low != high) {
            dseg[2 * ind + 1] += update;
            dseg[2 * ind + 2] += update;
        }
        return;
    }
  
    
    int mid = (low + high) / 2;
    rangeQuery(2 * ind + 1, low,
               mid, l, r, update,
               type);
  
    rangeQuery(2 * ind + 2, mid + 1,
               high, l, r, update,
               type);
  
    
    
    seg[ind] = seg[2 * ind + 1]
               + seg[2 * ind + 2];
  
    segSum[ind] = segSum[2 * ind + 1]
                  + segSum[2 * ind + 2];
}
  

void printAnswer(
    vector query,
    int N, int X)
{
    
    build(0, 0, N – 1);
  
    
    for (int i = 0;
         i < query.size(); i++) {            int l = query[i][0];         int r = query[i][1];         if (query[i][2] == 0) {                                                       rangeQuery(0, 0, N - 1, l, r, X, 0);         }         else if (query[i][2] == 1) {                                                       rangeQuery(0, 0, N - 1,                        l, r, X, 1);         }         else {             cout