Topics

We are given an array of size . For each query with parameters , , and , we need to compute the sum of consecutive subarrays starting at each index from to , where each subarray runs from the current index up to . In other words, for each valid starting index , we sum

Then, we output the total sum over all starting indices from to .

For example, with array and query :

  • First window: [size=4]
  • Second window: [size=4]
  • Third window: [size=3]
  • Fourth window: [size=2]
  • Fifth window: [size=1]
  • Total sum = 50

Input

  • Line 1: Integer
  • Line 2: Array elements
  • Line 3: Integer
  • Next lines: Three integers , , per line

Constraints

Sample

Input:

5
1 2 3 4 5
3
1 5 4
1 1 2
1 3 4

Output:

50
1
14

Explanations

  1. Query :
  2. Query : Single element
  3. Query :

Idea

The solution uses prefix sums to quickly compute sums over subarrays. We precompute:

  • The prefix sum array:
  • A secondary prefix array (prefix of prefix sums):

Similarly, we compute right prefix sums for handling cases where is larger than the length of the interval:

  • Right prefix sum array:
  • And its prefix:

The main challenge is handling the two distinct cases based on the relation between and the length of the query interval .

1. When

In this case, the window of elements fits completely for many starting indices. The sum is divided into two parts:

  • Full Window Sums: For indices from to , the window covers exactly elements. Each sum is . Using the prefix sum arrays, these sums can be computed quickly and then summed over (refer weird sum (easy) for formula derivation)
  • Decreasing Window Sums: For indices from to , the window would naturally extend past , so we only take up to . The sum for these indices is , which forms a decreasing sequence of window lengths (from elements down to ). Here, the right prefix sums come into play to compute the total sum efficiently.

Combining these two parts gives the answer when is small enough.

2. When

If is larger than the number of elements in the interval, then for every starting index , the window always runs from to . Thus, the sum becomes:

Using the right prefix sums, this can be computed by taking the difference:

Thus, by precomputing both prefix and right prefix sums, we can efficiently answer each query in constant time.

Code

void solve() {
  int n, q;
  cin >> n;
  vector<ll> arr(n + 1);
  vector<ll> prefix(n + 1, 0);
  vector<ll> prefix2(n + 1, 0);
  vector<ll> rPrefix(n + 2, 0);
  vector<ll> rPrefix2(n + 2, 0);
 
  for (int i = 1; i <= n; ++i) {
    cin >> arr[i];
    prefix[i] = prefix[i - 1] + arr[i];
  }
 
  for (int i = 1; i <= n; ++i) {
    prefix2[i] = prefix[i] + prefix2[i - 1];
  }
 
  for (int i = n; i > 0; --i) {
    rPrefix[i] = arr[i] + rPrefix[i + 1];
  }
 
  for (int i = n; i > 0; --i) {
    rPrefix2[i] = rPrefix[i] + rPrefix2[i + 1];
  }
 
  int l, r, k;
  cin >> q;
  while (q--) {
    cin >> l >> r >> k;
 
    ll part1 = 0;
    ll part2 = (rPrefix2[l] - rPrefix2[r + 1]) - (rPrefix[r + 1] * (r - l + 1));
 
    if (k <= r - l + 1) {
      ll part1_first = prefix2[r] - prefix2[l + k - 2];
      ll part1_second = prefix2[r - k] - (l - 2 >= 0 ? prefix2[l - 2] : 0);
      part1 = part1_first - part1_second;
 
      ll part2_first = rPrefix2[r - k + 2] - rPrefix2[r + 1];
      ll part2_second = rPrefix[r + 1] * (k - 1);
      part2 = part2_first - part2_second;
    }
 
    // cout << part2 << endl;
    cout << part1 + part2 << '\n';
  }
}