2197 - taietura

From Bitnami MediaWiki
Revision as of 16:15, 12 February 2024 by Aurelia Raluca (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Enunt[edit | edit source]

Fiind dat un șir V format din N numere întregi V[1], …, V[N], definim o tăietură în poziția pos ca fiind o subsecvență care conține elementul de pe poziția pos. Formal, tăieturile în poziția pos sunt de forma V[k], V[k+1], …, V[pos], …, V[r-1], V[r] pentru orice k, 1 ≤ k ≤ pos și orice r, pos ≤ r ≤ N. Valoarea unei tăieturi este suma tuturor elementelor care fac parte din tăietura respectivă. Definim funcția MulT(pos) ca fiind numărul de tăieturi în poziția pos care au valoarea 0.

Cerința[edit | edit source]

Ioana, fiind foarte curioasă din fire, dar și foarte fascinată de această funcție numită MulT, este foarte interesată în a afla rezultatul pentru MulT(i), unde 1 ≤ i ≤ N.

Date de intrare[edit | edit source]

Fișierul de intrare taietura.in conţine pe prima linie un număr natural N, reprezentând numărul de elemente din șirul V. Următoarea linie va conține exact N valori întregi despărțite prin câte un spațiu, și anume elementele șirului V.

Date de ieșire[edit | edit source]

Fișierul de ieșire taietura.out va conţine pe prima linie N numere naturale separate prin câte un spațiu, și anume valorile funcției MulT(i), unde 1 ≤ i ≤ N. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".

Restricții și precizări[edit | edit source]

  • 1 ≤ N ≤ 100 000
  • Orice element al șirului V este mai mic sau egal în valoare absolută cu 1 000 000 000
  • Pentru teste în valoare de 20 de puncte N ≤ 100
  • Pentru teste în valoare de încă 20 de puncte N ≤ 1000

Exemplul 1:[edit | edit source]

taieturaIN.txt

3
0 1 0

taieturaOUT.txt

1 0 1

Explicație[edit | edit source]

Rezultatul pentru MulT(1) este 1 deoarece există o singură tăietură, și anume (0) care are valoarea 0. Pentru MulT(2) rezultatul este 0 deoarece nu există nicio tăietură aplicată pe poziția 2 care să aibă valoarea 0. Rezultatul pentru MulT(3) este 1 deoarece există o unică tăietură, si anume (0) care are valoarea 0.

Exemplul 1:[edit | edit source]

taieturaIN.txt

3
0 1 0

taieturaOUT.txt

1 0 1

Rezolvare[edit | edit source]

<syntaxhighlight lang="python3" line="1"> def verificare_restrictii(N):

   if not (1 <= N <= 100000):
       with open("taieturaOUT.txt", "w") as f_out:
           f_out.write("Datele nu corespund restrictiilor impuse\n")
       return False
   return True

def main():

   with open("taieturaIN.txt", "r") as f_in, open("taieturaOUT.txt", "w") as f_out:
       N = int(f_in.readline().strip())
       if not verificare_restrictii(N):
           return
       V = [0] + list(map(int, f_in.readline().split()))
       if not all(-1000000000 <= v <= 1000000000 for v in V[1:]):
           with open("taieturaOUT.txt", "w") as f_out:
               f_out.write("Datele nu corespund restrictiilor impuse\n")
           return
       partial_sum = [0] * (N + 1)
       for i in range(1, N + 1):
           partial_sum[i] = partial_sum[i - 1] + V[i]
       sums = sorted(set(partial_sum))
       mars = [0] * (N + 1)
       count = [0] * len(sums)
       for i in range(N + 1):
           sum_index = sums.index(partial_sum[i])
           to_the_left = count[sum_index]
           if i < N:
               mars[i + 1] -= to_the_left
           count[sum_index] += 1
       for i in range(N):
           sum_index = sums.index(partial_sum[i])
           count[sum_index] -= 1
           to_the_right = count[sum_index]
           mars[i + 1] += to_the_right
       answer = 0
       for i in range(1, N + 1):
           answer += mars[i]
           f_out.write(f"{answer} ")

if __name__ == "__main__":

   main()

</syntaxhighlight>