Minimum Cəmi Quruluşu#12262

Minimum Cəmi Quruluşu (Həll təhlili)

Problem Müəllifi:

Hasan Saleh (MathModel)

Hazırlayan:

Hasan Saleh (MathModel)

Redaktə edən:

Hasan Saleh (MathModel)

Həll

Bizdən 1 \le A_i \le n, \sum_{i=1}^n A_i = a və \sum_{i=1}^n \min(A_i,b) = c olan uzunluğunda massivini qurmağı xahiş edirlər. Minimumla bağlı şərt məhdudlaşdırıcıdır, buna görə əvvəlcə bu cəmi düzgün edirik, sonra isə real cəmi düzəldirik.

Qeyd edin ki, biz heç vaxt -dan böyük bir dəyərdən başlamalı deyilik, çünki dəyərlər hər halda ilə məhdudlaşır və olan hər hansı bir dəyər məhdud cəminə eyni töhfəni verir. B = \min(b,n) olsun. Əgər biz

A_i = B \quad \text{hər } i=1,\dots,n \text{ üçün,}

o zaman hazırda

\sum_{i=1}^n \min(A_i,b) = \sum_{i=1}^n B = n \cdot B,

və həmçinin

\sum_{i=1}^n A_i = n \cdot B.

Bu cari məhdud cəmi \text{tot} = n \cdot B adlandıraq.

Biz məhdud cəmin tam olaraq olmasını istəyirik. Hazırda hər A_i \le B \le b olduğuna görə, A_i-ni azaldaraq \min(A_i,b)-ni də azaldacağıq. Beləliklə, i=1-dən -ə qədər irəliləyirik və \text{tot} > c olduğu müddətdə A_i-ni azaltmağa çalışırıq. Müəyyən bir mövqeyi üçün daha çox azalda bilmirik, çünki hələ də artıqdır, və -dən aşağı düşə bilmərik, buna görə

v = \min\{\, \text{tot} - c,\; A_i - 1,\; B - 1 \,\}

alırıq və

A_i \gets A_i - v,\quad \text{tot} \gets \text{tot} - v.

Bir keçiddən sonra bərabərlik

\sum_{i=1}^n \min(A_i,b) = c

yerinə yetirilir, çünki bəzi A_i \le b-dən çıxardığımız hər bir vahid məhdud cəmi dəqiq azaldır.

İndi real cəmi \sum A_i-ni yoxlayırıq. Əgər b \ge n-dirsə, onda B = n və \min(A_i,b) = A_i bütün üçün, beləliklə, məhdud cəm olduqda artıq \sum A_i = c-dir, və bəyanatın garantiyası ilə bir həllin mövcud olduğunu bildiyimiz üçün a=c olmalıdır və işimiz bitdi.

Əgər b \le n-dirsə, onda azaldılma mərhələsindən sonra məhdud cəm düzgün, lakin bəlkə də

\sum_{i=1}^n A_i < a.

Realdan cəmi artırmaq üçün yalnız A_i = b olan mövqeləri dəyişdiririk. Belə bir A_i-ni b + \delta-ya artırdıqda, burada \delta \le n-b, onda

\min(A_i,b) = b \quad \text{(dəyişməz)},

amma real cəm ilə artır. Beləliklə, yenidən skan edirik və hər dəfə A_i = b olduqda və cari cəm hələ də olduqda, biz

\delta = \min(a - \text{cəm},\; n - b)

A_i-yə əlavə edirik. Problemin bir həllin mövcud olduğunu vəd etdiyi üçün, dəqiq cəm -ya çatmaq üçün kifayət qədər belə mövqeləri tapacağıq. A_i \le n şərtini heç vaxt pozmuruq, çünki yalnız -dən -ə qədər artırırıq.

Beləliklə, quruluş aşağıdakı kimidir:

  1. hər şeyi B = \min(b,n)-ya təyin edin;

  2. ön tərəfdən azaldın ki, məhdud cəm -ya bərabər olsun;

  3. əgər b \le n-dirsə, yalnız hazırda -ya bərabər olan mövqeləri artırın ki, real cəm -ya bərabər olsun.

Komplekslik \mathcal{O}(\sum n)-dir.

for _ in range(int(input())):
    n,a,b,c=map(int,input().split())
    base=min(b,n)
    res=[base]*n
    tot=n*base
    i=0
    while i<n and tot>c:
        v=min(tot-c,res[i]-1,base-1)
        if v>0:
            res[i]-=v
            tot-=v
        i+=1
    if b<=n:
        i=0
        while i<n and tot<a:
            if res[i]==b:
                v=min(a-tot,n-b)
                if v>0:
                    res[i]+=v
                    tot+=v
            i+=1
    print(*res)