1. Concise problem statement  
Given K zones, each with capacity Ci and quality Qi, and N = ΣCi students, each with skill Pj and weight wj. Assign each student to exactly one zone (respecting capacities) to maximize the total weight of students for whom Pj > Q (zone’s quality). Output for each student the index of their assigned zone.

2. Detailed editorial  

Problem restated as a weighted assignment: we have N students and N slots (zone seats). A student j assigned to zone i yields profit wj if Pj > Qi, otherwise 0. Capacities Ci sum to N. We must fill every slot exactly once. We want the maximum total profit.

Observation: if a student cannot beat any zone’s quality, assigning him anywhere gives 0, so his placement doesn’t affect profit. If he can beat at least one zone, we’d rather use him for one of those zones to collect his weight.

This is isomorphic to the “scheduling with deadlines and profits” problem:

  - Each student is a “job” with profit = wj and deadline = the count of all available seats in zones with Q < Pj.
  - Each seat is a “time slot”. If we schedule the job by its deadline, we earn its profit.

The greedy algorithm for scheduling with deadlines and profits says:  
 1. Sort jobs (students) by descending profit w.  
 2. For each job in that order, attempt to schedule it in the latest available slot ≤ its deadline.  
 3. If successful, we collect the profit; if no slot is free before the deadline, we skip it (or leave it for later zero-profit assignment).  
 4. At the end, assign all unscheduled jobs into the remaining slots arbitrarily (they earn zero).

Mapping back to zones:  
  - Sort students by w descending.  
  - Sort zones by Q ascending.  
  - For each student, find the zone with the largest Q < P that still has free capacity (this corresponds to the latest slot). If found, assign him there and decrement its capacity.  
  - Otherwise, leave him unassigned for now.  
  - After processing all students, fill unassigned students into any zones that still have capacity.

This runs in O(N·K) (K≤100, N≤16 000), which is fine.

3. C++ solution with detailed comments  

#include <bits/stdc++.h>  
using namespace std;  

// A zone has a quality 'q', a remaining capacity 'cap', and original index 'id'.  
struct Zone {  
    int q, cap, id;  
};  

// A student has skill 'p', weight 'w', and original index 'id'.  
struct Student {  
    int p, w, id;  
};  

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

    int K;  
    cin >> K;  // number of zones  

    // Read capacities and sum to get total students  
    vector<Zone> zones(K);  
    long long totalN = 0;  
    for(int i = 0; i < K; i++) {  
        cin >> zones[i].cap;  // Ci  
        totalN += zones[i].cap;  
    }  

    // Read zone qualities  
    for(int i = 0; i < K; i++) {  
        cin >> zones[i].q;  
        zones[i].id = i;  // store original index  
    }  

    // Read student skills and weights  
    vector<Student> students(totalN);  
    for(int i = 0; i < totalN; i++) {  
        cin >> students[i].p;  // Pj  
    }  
    for(int i = 0; i < totalN; i++) {  
        cin >> students[i].w;  // wj  
        students[i].id = i;    // original student index  
    }  

    // Sort students by descending weight  
    sort(students.begin(), students.end(), [&](auto &a, auto &b) {  
        return a.w > b.w;  
    });  

    // Sort zones by ascending quality  
    sort(zones.begin(), zones.end(), [&](auto &a, auto &b) {  
        return a.q < b.q;  
    });  

    // answer[i] = assigned zone index (1-based) for student i  
    vector<int> answer(totalN, -1);  

    // Greedily assign heavy students to the best qualifying zone
    for(auto &st : students) {  
        int best = -1;  
        // scan zones from highest Q down to lowest  
        for(int j = K - 1; j >= 0; j--) {  
            // if zone quality < student skill and zone has capacity  
            if(zones[j].q < st.p && zones[j].cap > 0) {  
                best = j;  
                break;  
            }  
        }  
        if(best != -1) {  
            // assign this student to that zone  
            answer[st.id] = zones[best].id + 1;  
            zones[best].cap--;  
        }  
    }  

    // Fill remaining students (those with answer == -1) into any leftover slots  
    int zptr = 0;  
    for(int i = 0; i < totalN; i++) {  
        if(answer[i] == -1) {  
            // find next zone with free capacity  
            while(zptr < K && zones[zptr].cap == 0) zptr++;  
            answer[i] = zones[zptr].id + 1;  
            zones[zptr].cap--;  
        }  
    }  

    // Output the assignments in the original student order  
    for(int i = 0; i < totalN; i++) {  
        cout << answer[i] << (i + 1 < totalN ? ' ' : '\n');  
    }  

    return 0;  
}  

4. Python solution with detailed comments  

import sys  
def main():  
    data = sys.stdin.read().split()  
    it = iter(data)  
    K = int(next(it))  

    # Read capacities and compute total number of students  
    caps = [int(next(it)) for _ in range(K)]  
    totalN = sum(caps)  

    # Read zone qualities  
    qs = [int(next(it)) for _ in range(K)]  

    # Read student skills and weights  
    ps = [int(next(it)) for _ in range(totalN)]  
    ws = [int(next(it)) for _ in range(totalN)]  

    # Build zone objects: (quality, remaining capacity, original index)  
    zones = sorted([ [qs[i], caps[i], i] for i in range(K) ], key=lambda z: z[0])  

    # Build student objects: (weight, skill, original index)  
    students = sorted([ [ws[i], ps[i], i] for i in range(totalN) ],  
                      key=lambda s: -s[0])  # descending weight  

    # Placeholder for answers  
    answer = [-1]*totalN  

    # Greedy assignment: heavy students first  
    for w, p, sid in students:  
        # scan zones from highest quality down  
        for j in range(K-1, -1, -1):  
            q, cap, zid = zones[j]  
            if q < p and cap > 0:  
                answer[sid] = zid + 1  
                zones[j][1] -= 1  # decrease capacity  
                break  

    # Fill leftovers  
    zptr = 0  
    for i in range(totalN):  
        if answer[i] == -1:  
            # find next zone with capacity  
            while zones[zptr][1] == 0:  
                zptr += 1  
            answer[i] = zones[zptr][2] + 1  
            zones[zptr][1] -= 1  

    # Print results  
    print(" ".join(map(str, answer)))  

if __name__ == "__main__":  
    main()  

5. Compressed editorial  
- Model as scheduling “jobs” (students) with profit w and deadline = total seats in zones with Q < P.  
- Greedy: sort students by descending w. For each, place in the latest qualifying zone (highest Q < P) with remaining capacity.  
- Leftover students go to any free slots. This maximizes the total weight of P>Q assignments.