#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int MOD = 1000000007;
// LCT Node
struct Node {
int p, ch[2];
long long weight, sum_weight;
int vir_sz, total_sz;
} tr[300005];
inline void pushup(int x) {
long long sw = tr[x].weight;
int ts = tr[x].vir_sz + 1;
if (tr[x].ch[0]) {
sw += tr[tr[x].ch[0]].sum_weight;
ts += tr[tr[x].ch[0]].total_sz;
}
if (tr[x].ch[1]) {
sw += tr[tr[x].ch[1]].sum_weight;
ts += tr[tr[x].ch[1]].total_sz;
}
tr[x].sum_weight = sw % MOD;
tr[x].total_sz = ts;
}
inline bool is_root(int x) {
return tr[tr[x].p].ch[0] != x && tr[tr[x].p].ch[1] != x;
}
inline void rotate(int x) {
int y = tr[x].p, z = tr[y].p;
int k = (tr[y].ch[1] == x);
if (!is_root(y)) tr[z].ch[tr[z].ch[1] == y] = x;
tr[x].p = z;
tr[y].ch[k] = tr[x].ch[k ^ 1];
if (tr[x].ch[k ^ 1]) tr[tr[x].ch[k ^ 1]].p = y;
tr[x].ch[k ^ 1] = y;
tr[y].p = x;
pushup(y);
pushup(x);
}
inline void splay(int x) {
if (x == 0) return; // FIX: Prevent infinite loop on the dummy root
while (!is_root(x)) {
int y = tr[x].p, z = tr[y].p;
if (!is_root(y)) {
if ((tr[y].ch[1] == x) ^ (tr[z].ch[1] == y)) rotate(x);
else rotate(y);
}
rotate(x);
}
}
inline void access(int x) {
if (x == 0) return; // FIX: Prevent virtual pathing on the dummy root
for (int y = 0; x; y = x, x = tr[x].p) {
splay(x);
if (tr[x].ch[1]) tr[x].vir_sz += tr[tr[x].ch[1]].total_sz;
if (y) tr[x].vir_sz -= tr[y].total_sz;
tr[x].ch[1] = y;
pushup(x);
}
}
inline void cut(int x) {
access(x); splay(x);
tr[tr[x].ch[0]].p = 0;
tr[x].ch[0] = 0;
pushup(x);
}
inline void link(int x, int y) {
access(x); splay(x);
access(y); splay(y);
tr[x].p = y;
tr[y].vir_sz += tr[x].total_sz;
pushup(y);
}
struct Query {
int x, id;
bool operator<(const Query& other) const {
return x < other.x;
}
};
int main() {
// Fast I/O
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n, k;
if (!(cin >> n >> k)) return 0;
vector<pair<int, int>> events;
for (int i = 1; i <= n; i++) {
int val;
cin >> val;
events.push_back({val, i});
}
// Sort array values ascending to know exactly when they deactivate
sort(events.begin(), events.end());
int q;
cin >> q;
vector<Query> queries(q);
for (int i = 0; i < q; i++) {
cin >> queries[i].x;
queries[i].id = i;
}
// Sort queries ascending
sort(queries.begin(), queries.end());
// 1. Precalculate initial sizes for x = 0 in O(N)
vector<int> initial_sz(n + 1, 1);
for (int i = n; i >= 1; i--) {
int p = max(0, i - k);
initial_sz[p] += initial_sz[i];
}
// 2. Initialize the Link-Cut Tree optimally
for (int i = 1; i <= n; i++) {
tr[i].p = max(0, i - k);
tr[i].weight = i;
tr[i].sum_weight = i;
tr[i].total_sz = initial_sz[i];
tr[i].vir_sz = initial_sz[i] - 1; // Initially all children are virtual
tr[i].ch[0] = tr[i].ch[1] = 0;
}
tr[0].p = 0;
tr[0].weight = 0;
tr[0].sum_weight = 0;
tr[0].total_sz = initial_sz[0];
tr[0].vir_sz = initial_sz[0] - 1;
tr[0].ch[0] = tr[0].ch[1] = 0;
long long S = 0;
for (int i = 1; i <= n; i++) {
S = (S + 1LL * initial_sz[i] * i) % MOD;
}
// 3. Process Queries Offline
vector<long long> ans(q);
int e_ptr = 0;
for (int i = 0; i < q; i++) {
// While the active element flips to inactive
while (e_ptr < n && events[e_ptr].first <= queries[i].x) {
int idx = events[e_ptr].second;
// Fetch properties before the cut
int old_p = max(0, idx - k);
access(old_p); splay(old_p);
long long dp_old = tr[old_p].sum_weight;
// Disconnect from i-k
cut(idx);
// Fetch exactly the isolated subtree size
access(idx); splay(idx);
long long sz_i = tr[idx].total_sz;
// Nullify its weight
tr[idx].weight = 0;
pushup(idx);
// Fetch properties of the new parent
int new_p = idx - 1;
access(new_p); splay(new_p);
long long dp_new = tr[new_p].sum_weight;
// Connect to i-1
link(idx, new_p);
// Mathematically deduce the exact delta on the total answer
long long delta = (dp_new - dp_old - idx) % MOD;
if (delta < 0) delta += MOD;
S = (S + (sz_i % MOD) * delta) % MOD;
e_ptr++;
}
ans[queries[i].id] = S;
}
for (int i = 0; i < q; i++) {
cout << ans[i] << "\n";
}
return 0;
}