<|instruction|>
Solve the below problem. The solution should start with an abridged problem statement. Then key observations. Then full solution based on the observations. Then C++ and Python implementations with comments.

379. Elevator
Time limit per test: 0.75 second(s)
Memory limit: 65536 kilobytes
input: standard
output: standard



There is only one elevator in the tall building with N floors. The parking for this building is at the basement floor which is located under the first floor. All floors are enumerated from 1 to N, growing up. At i-th floor there are Ai people who wish to descend from the floor to parking. You know that the elevator is unable to carry more than C people at any time. Descending or ascending one floor takes P seconds. Your task is to find the maximum possible number of people the elevator may deliver to parking within T seconds of operation, if it is located at the parking in the beginning. You may assume that stopping at a stage to load or unload people is done instantly.

Input
In the first line of input file there are four integers N, C, P, T (1 ≤ N ≤ 100, 1 ≤ C ≤ 109, 1 ≤ P ≤ 109, 1 ≤ T ≤ 109). The second line contains the sequence of N integers A1, A2,..., AN (0 ≤ Ai ≤ 109). The sum of all Ai does not exceed 109 too.

Output
Output the maximum possible number of people who can reach the parking.

Example(s)
sample input
sample output
4 5 2 15
0 1 2 3
3

sample input
sample output
4 5 2 18
0 1 2 3
5

sample input
sample output
3 2 1 9
1 1 1
3

<|response|>
1. Abridged Problem Statement
We have a building with floors 1…N. On floor i there are Ai people wanting to go down to the basement (floor 0). An elevator of capacity C starts at the basement. Moving up or down one floor takes P seconds, and loading/unloading passengers takes no time. In at most T seconds, what is the maximum number of people the elevator can bring down?

2. Key Observations
- Any trip consists of going up to some highest floor h (possibly stopping on the way to pick people) and then returning to the basement. The time cost of such a round trip is 2·h·P.
- To maximize the number of people carried within time T, if we decide to carry exactly x people, we should take them from the lowest floors first (they incur smaller trip heights).
- Once we select which x people to serve (pulling from floors 1 upward), we can split the work into:
  a. Full‐capacity trips of C people from each floor separately.
  b. Mixed trips for the remainders (< C people on each floor), always filling the car up to C by drawing from the highest remaining floors first (to minimize the trip height for each mixed load).
- We can test feasibility for a given x in O(N + number_of_trips) time. Then binary‐search on x to find the maximum deliverable.

3. Full Solution Approach
a. Binary search on x = number of people we aim to deliver.
   low = 1, high = 1e9 (an upper bound on people deliverable).
   While low ≤ high:
     mid = (low+high)/2
     if check(mid) is true, record answer=mid and set low=mid+1
     else set high=mid−1
   Output answer.

b. check(x): can we deliver exactly x people within time T?
   1. Greedily select x people from the lowest floors:
      rem[i] = min(Ai, remaining_x), scanning i=1…N until we assign all x.
      If sum(Ai)<x, return false.
   2. Compute time for full‐capacity trips:
      For each floor i where rem[i]>0:
        full_trips = rem[i] / C
        time += full_trips * (2·i·P)
        rem[i] %= C
        If at any point time > T, return false.
   3. Gather all floors with rem[i]>0 into a list ordered by increasing i.
   4. While the leftover list is nonempty:
        Let h = highest floor in the list (last element).
        time += 2·h·P
        If time > T, return false.
        Fill the elevator up to capacity C by taking from the highest floors first, decrementing rem[i] accordingly and removing floors when rem[i] reaches zero.
   5. If total time ≤ T, return true, else false.

Because each mixed trip serves up to C leftover people and N≤100, this is efficient. The overall complexity is O((N + trips) · log(1e9)), well within limits.

4. C++ Implementation

```cpp
#include <bits/stdc++.h>

using namespace std;

template<typename T1, typename T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& x) {
    return out << x.first << ' ' << x.second;
}

template<typename T1, typename T2>
istream& operator>>(istream& in, pair<T1, T2>& x) {
    return in >> x.first >> x.second;
}

template<typename T>
istream& operator>>(istream& in, vector<T>& a) {
    for(auto& x: a) {
        in >> x;
    }
    return in;
};

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
};

int n, c, p, t;
vector<int> cnt;

void read() {
    cin >> n >> c >> p >> t;
    cnt.resize(n);
    cin >> cnt;
}

bool check(int x) {
    vector<int> li;
    for(int i = 0; i < n; i++) {
        li.push_back(min(x, cnt[i]));
        x -= cnt[i];
        if(x <= 0) {
            break;
        }
    }

    if(x > 0) {
        return false;
    }

    int64_t ret = 0;
    for(int i = 0; i < (int)li.size(); i++) {
        int whole = li[i] / c;
        if(whole * 1ll * p > t) {
            return false;
        }

        ret += whole * 1ll * (i + 1) * 2ll * p;
        if(ret > t) {
            return false;
        }

        li[i] %= c;
    }

    while(!li.empty() && li.back() == 0) {
        li.pop_back();
    }

    while(!li.empty()) {
        ret += li.size() * 1ll * p * 2ll;
        if(ret > t) {
            return false;
        }

        int cap = 0;
        while(!li.empty()) {
            int curr = min(c - cap, li.back());
            cap += curr;
            if(curr == li.back()) {
                li.pop_back();
            } else {
                li[li.size() - 1] -= curr;
                break;
            }
        }
    }

    return ret <= t;
}

void solve() {
    // Binary search on x, the number of people delivered to the parking, and
    // test feasibility within T seconds with a greedy check.
    //
    // To deliver x people optimally we always pick people from the lowest
    // floors first (cheaper trips), capping each floor by its population. For a
    // floor that contributes full elevator loads, each full load of C costs a
    // dedicated round trip of 2 * (floor index) * P seconds. The remaining
    // partial loads (the modulo-C residue of each floor) are merged greedily
    // from the top downward: each trip fills up to C people and its cost is
    // 2 * P * (highest floor still holding leftovers). Accumulate the time and
    // reject as soon as it exceeds T; the largest feasible x is the answer.

    int low = 1, high = (int)1e9, ret = 0;
    while(low <= high) {
        int mid = (low + high) >> 1;
        if(check(mid)) {
            ret = mid;
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }

    cout << ret << '\n';
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int T = 1;
    // cin >> T;
    for(int test = 1; test <= T; test++) {
        read();
        // cout << "Case #" << test << ": ";
        solve();
    }

    return 0;
}
```

5. Python Implementation with Detailed Comments
```python
import sys
sys.setrecursionlimit(10**7)

def can_deliver(x, N, C, P, Tlimit, A):
    # 1) Pick x people from lowest floors
    rem = []   # list of [floor, count]
    need = x
    for i in range(1, N+1):
        if need <= 0:
            break
        take = min(need, A[i])
        if take > 0:
            rem.append([i, take])
            need -= take
    if need > 0:
        return False  # not enough people

    time_used = 0

    # 2) Full-capacity trips per floor
    for floor, cnt in rem:
        full_trips = cnt // C
        time_used += full_trips * (2 * floor * P)
        if time_used > Tlimit:
            return False
        # leftovers on this floor
        cnt %= C
        # update in rem list
        # we will rebuild leftovers next

    # 3) Build leftover list (<C each)
    leftover = []
    for floor, cnt in rem:
        if cnt > 0:
            leftover.append([floor, cnt])

    # 4) Mixed trips for leftovers
    while leftover:
        highest = leftover[-1][0]
        time_used += 2 * highest * P
        if time_used > Tlimit:
            return False

        cap = 0
        # fill elevator up to C
        while cap < C and leftover:
            floor, cnt = leftover[-1]
            take = min(C - cap, cnt)
            cap += take
            cnt -= take
            if cnt == 0:
                leftover.pop()
            else:
                leftover[-1][1] = cnt

    return time_used <= Tlimit

def main():
    data = sys.stdin.read().split()
    it = iter(data)
    N = int(next(it))
    C = int(next(it))
    P = int(next(it))
    Tlimit = int(next(it))
    A = [0] + [int(next(it)) for _ in range(N)]

    # Binary search on x
    low, high = 0, sum(A)
    answer = 0
    while low <= high:
        mid = (low + high) // 2
        if can_deliver(mid, N, C, P, Tlimit, A):
            answer = mid
            low = mid + 1
        else:
            high = mid - 1

    print(answer)

if __name__ == "__main__":
    main()
```
