Topics
Given array of integers, answer queries. For each query , we need to find sum of all possible consecutive subsequences of length starting from index up to index .
In other words:
- Take consecutive elements starting at index :
- Take consecutive elements starting at index :
- Continue this pattern until reaching the last possible subsequence ending at index
For example, with array and query :
- First subsequence:
- Second subsequence:
- Sum =
The mathematical expression is:
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
2
2 4 2
1 1 1
Output:
12
1
Explanation:
Query 1:
Query 2: Single element sum:
Idea
Use two levels of prefix sums to transform each query into O(1) operation.
1. Build First Prefix Sum (P)
Let with
This allows computing any subarray sum in O(1):
2. Query Expression
For query :
- Initial form:
- Split into:
- After reindexing:
3. Build Second Prefix Sum (PP)
Let with
This transforms range sums of P into O(1):
4. Final Query Formula
Answer = (PP[r] - PP[l+k-2]) - (PP[r-k] - (l-2 ≥ 0 ? PP[l-2] : 0))
- Time Complexity: preprocessing + queries
- Space Complexity:
Code
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int N;
cin >> N;
vector<ll> A(N + 1);
for (int i = 1; i <= N; i++) {
cin >> A[i];
}
vector<ll> P(N + 1, 0);
for (int i = 1; i <= N; i++) {
P[i] = P[i - 1] + A[i];
}
vector<ll> PP(N + 1, 0);
PP[0] = P[0]; // P[0] is 0.
for (int i = 1; i <= N; i++) {
PP[i] = PP[i - 1] + P[i];
}
int Q;
cin >> Q;
while (Q--) {
int l, r, k;
cin >> l >> r >> k;
// Calculate sum_{j = l+k-1}^{r} P[j]
ll sumFirst = PP[r] - PP[l + k - 2];
// Calculate sum_{j = l-1}^{r-k} P[j]
ll sumSecond = PP[r - k] - (l - 2 >= 0 ? PP[l - 2] : 0);
ll answer = sumFirst - sumSecond;
cout << answer << "\n";
}
return 0;
}