2453 - Rosii Mici

De la Universitas MediaWiki

Dan este un mare pasionat al fructelor, printre preferatele sale fiind strugurii şi pepenii. Însă recent şi-a descoperit și pasiunea pentru legume, în special pentru roşii, dar mai ales roşiile mici. Spre norocul lui, grădina bunicului este plină de roşii. Grădina are forma unei matrice cu N linii și M coloane cu elemente numere naturale, nu neapărat distincte, unde fiecare element din matrice reprezintă dimensiunea unei roşii. Matricea are proprietatea că oricare coloană are valorile ordonate crescător de sus în jos, adică de la prima spre ultima linie. Bunicul său îi cere să rezolve Q sarcini. Pentru fiecare sarcină, Dan primeşte un număr natural x şi trebuie să găsească o submatrice de arie maximă care începe de pe linia 1 a matricei care reprezintă grădina şi are toate elementele mai mici sau egale decât x. Pentru determinarea submatricei cerute, Dan are voie să mute toate valorile unei coloane în fața oricărei alte coloane. De asemenea, îi este permis să facă oricâte mutări de tipul acesta.

Cerința

Să se calculeze aria maximă a unei submatrice care respectă specificațiile din enunț, pentru fiecare din cele Q sarcini date de către bunic.

Date de intrare

Fișierul de intrare input.txt conține pe prima linie trei numere naturale N, M și Q separate printr-un spaţiu, având semnificația din enunț. Pe fiecare dintre următoarele N linii se află câte M numere naturale despărțite prin câte un spațiu, reprezentând valorile matricei. Pe următoarele Q linii se află câte un număr natural x, reprezentând dimensiunea unei roşii.

Date de ieșire

Fișierul de ieșire output.txt va conține pe primele Q linii câte un număr natural, reprezentând aria maximă cerută

pentru fiecare sarcină, în ordinea în care acestea apar în fișierul de intrare.

Restricții și precizări

  • 1 ≤ N, M ≤ 1000
  • 1 ≤ Q ≤ 100 000
  • 1 ≤ A[i][j] ≤ N * M, 1 ≤ i ≤ N, 1 ≤ j ≤ M

Exemplul 1

input.txt:

3 4 3

1 9 6 2

1 10 10 4

7 15 10 6

6

10

9

output.txt:

4

9

6

Explicație:

Pentru rezolvarea primei sarcini Dan mută prima coloană în fața celei de a patra obținând matricea:

9 6 1 2

10 10 1 4

15 10 7 6

Alege apoi submatricea cu colțul stânga sus în (1,3) și colțul dreapta jos în (2,4). Aria acesteia este 4.

Pentru rezolvarea celei de a doua sarcini, Dan mută prima coloană în fața celei de a treia obținând matricea:

9 1 6 2

10 1 10 4

15 7 10 6

Soluția este submatricea cu colțul stânga sus în (1,2) și colțul dreapta jos în (3,4). Aria acesteia este 9.

Pentru rezolvarea celei de a treia sarcini, Dan mută ultima coloană în fața primei coloane, obținând matricea:

2 1 9 6

4 1 10 10

6 7 15 10

Soluția este submatricea cu colțul stânga sus în (1,1) și colțul dreapta jos în (3,2). Aria acesteia este 6.

Exemplul 2

input.txt:

9999999 4 3

1 9 6 2

1 10 10 4

7 15 10 6

6

10

9

Output:

ValueError: Error: 1 <= n <= 1000

Rezolvare

def verify_constraints(n, m, q):
    if not (1 <= n <= 1000):
        raise ValueError("Error: 1 <= n <= 1000")
    if not (1 <= m <= 1000):
        raise ValueError("Error: 1 <= m <= 1000")
    if not (1 <= q <= 100000):
        raise ValueError("Error: 1 <= q <= 100000")

def main():
    def read_int():
        return int(fin.readline().strip())

    with open("input.txt", "r") as fin, open("output.txt", "w") as fout:
        n, m, q = map(int, fin.readline().split())
        verify_constraints(n, m, q)

        positions = [[] for _ in range(n * m + 5)]
        minn = [0] * m
        height = [0] * (m + 1)
        sum_ = [0] * (n + 1)
        ans = [0] * (n * m + 5)
        sol = 0

        for i in range(n):
            row = list(map(int, fin.readline().split()))
            for j in range(m):
                x = row[j]
                if not (minn[j] <= x):
                    raise ValueError("Error: minn[j] <= x")
                minn[j] = x
                positions[x].append(j)

        for val in range(1, n * m + 1):
            for j in positions[val]:
                height[j] += 1
                sum_[height[j]] += 1
                sol = max(sol, sum_[height[j]] * height[j])
            ans[val] = sol

        for i in range(1, n * m + 1):
            ans[i] = max(ans[i - 1], ans[i])

        for _ in range(q):
            x = read_int()
            fout.write(str(ans[x]) + "\n")

if __name__ == "__main__":
    main()