3705 - rectangles: Difference between revisions

From Bitnami MediaWiki
No edit summary
 
Line 1: Line 1:
== Cerinta ==
== Cerinta ==


Să se calculeze restul împărțirii sumei ariilor dreptunghiurilor ce caracterizează toate rectangle-sequences din șir la numărul 1.000.000.007.
Se consideră un șir de <code>N</code> numere naturale. Numim rectangle-sequence orice secvență continuă din șir (formată din elemente situate pe poziții consecutive) care conține cel puțin două elemente. Fiecare rectangle-sequence este caracterizată de un dreptunghi cu lungimile laturilor egale cu cele mai mari două elemente din cadrul ei.


== Date de intrare ==
= Cerința =
Să se calculeze restul împărțirii sumei ariilor dreptunghiurilor ce caracterizează toate rectangle-sequences din șir la numărul <code>1.000.000.007</code>.


Prima linie contine numărul natural nenul N, reprezentând numărul elementelor din șir, iar linia a doua conține, separate prin câte un spațiu, cele N elemente. Întrucât volumul datelor de intrare este foarte mare, vă recomandăm, în cazul în care folosiți pentru citire biblioteca iostream din standardul C++, să adaugați la începutul funcției main urmatoarele instrucțiuni:
= Date de intrare =
Prima linie contine numărul natural nenul <code>N</code>, reprezentând numărul elementelor din șir, iar linia a doua conține, separate prin câte un spațiu, cele <code>N</code> elemente. Întrucât volumul datelor de intrare este foarte mare, vă recomandăm, în cazul în care folosiți pentru citire biblioteca <code>iostream</code> din standardul C++, să adaugați la începutul funcției <code>main</code> urmatoarele instrucțiuni:
std :: iosbase :: sync_with_stdio (false);
std :: cin.tie(0);


*std :: iosbase :: sync_with_stdio (false);
= Date de ieșire =
*std :: cin.tie(0);
Ieșirea conține numărul de determinat, modulo <code>1.000.000.007</code>. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".


== Date de iesire ==
= Restricții și precizări =


Ieșirea conține numărul de determinat, modulo 1.000.000.007.
* <code>1 ≤ n ≤ 1.000.000</code>
* <code>1 ≤ orice element din șir 1 ≤ 1.000.000.000</code>
* Subtask 1 (13 puncte): <code>N ≤ 2000</code>
* Subtask 2 (23 puncte): <code>N ≤ 100.000</code> și există cel mult <code>100</code> de numere distincte în șir.
* Subtask 3 (27 puncte): <code>N ≤ 200.000</code>
* Subtask 4 (37 puncte): nu există restricții suplimentare


== Restrictii si precizari ==
= Exemplul 1: =
Intrare
3
2 3 1
Ieșire
15


*1 ≤ n ≤ 1.000.000
=== Explicație ===
*1 ≤ orice element din șir 1 ≤ 1.000.000.000
Sunt <code>3</code> rectangle-sequences: <code>(2; 3)</code>; <code>(2; 3; 1)</code>; <code>(3; 1)</code>. Ariile celor trei deptunghiuri ce le caracterizează sunt: <code>6</code>, <code>6</code>, <code>3</code>.
*Subtask 1 (13 puncte): N ≤ 2000
*Subtask 2 (23 puncte): N ≤ 100.000 și există cel mult 100 de numere distincte în șir.
*Subtask 3 (27 puncte): N ≤ 200.000
*Subtask 4 (37 puncte): nu există restricții suplimentare


== Exemplul 1 ==
== Exemplul 2: ==
Intrare
100000000000
2 3 1
Ieșire
Datele nu corespund restrictiilor impuse


; intrare
== Rezolvare ==
 
<syntaxhighlight lang="python3" line="1">
:3
MaxN = 1000010
:2 3 1
mod = 10**9 + 7


; iesire
v = [0] * MaxN
left1 = [0] * MaxN
left2 = [0] * MaxN
right1 = [0] * MaxN
right2 = [0] * MaxN


:Datele introduse corespund restrictiilor impuse.
def multiply(a, b, c, d):
 
     return ((a * b) % mod) * ((c * d) % mod) % mod
:15
 
==Exemplul 2 ==
 
; intrare
 
:-4
 
:300 143 235235
 
; iesire
 
:Datele de intrare nu corespund restrictiilor impuse.
 
== Rezolvare ==
<syntaxhighlight lang="python3" line="1">
#3705 - Rectangles
def rest_suma_arii_rectangle_sequences(arr):
     mod = 1000000007
    n = len(arr)


     stack = []
def citeste_si_verifica_elemente(n):
     suma_arii = 0
    print(f"Introduceți {n} elemente (fiecare urmat de Enter):")
     v_temp = []
     for i in range(1, n + 1):
        try:
            x = int(input(f"Elementul {i}: "))
            if not (1 <= x <= 10**9):
                print("Datele nu corespund restricțiilor impuse")
                return None
            v_temp.append(x)
        except ValueError:
            print("Datele nu corespund restricțiilor impuse")
            return None
    return v_temp


    for i in range(n):
def main():
         while stack and arr[i] >= arr[stack[-1]]:
    try:
             h = arr[stack.pop()]
         n = int(input("Introduceți lungimea șirului: "))
             w = i if not stack else i - stack[-1] - 1
        if not (1 <= n <= 10**6):
            suma_arii = (suma_arii + h * w) % mod
             print("Datele nu corespund restricțiilor impuse")
         stack.append(i)
             return
    except ValueError:
        print("Datele nu corespund restricțiilor impuse")
         return
   
    v_input = citeste_si_verifica_elemente(n)
    if v_input is None:
        return
   
    v[1:n+1] = v_input


     while stack:
     for i in range(1, n+1):
         h = arr[stack.pop()]
        left1[i] = left2[i] = 0
         w = n if not stack else n - stack[-1] - 1
        right1[i] = right2[i] = n + 1
        suma_arii = (suma_arii + h * w) % mod
   
    st1, st2, aux = [], [], []
    for i in range(1, n+1):
        while st2 and v[i] > v[st2[-1]]:
            right2[st2[-1]] = i
            st2.pop()
        while st1 and v[i] > v[st1[-1]]:
            right1[st1[-1]] = i
            aux.append(st1.pop())
        st1.append(i)
        while aux:
            st2.append(aux.pop())
   
    st1.clear()
    st2.clear()
   
    for i in range(n, 0, -1):
         while st2 and v[i] >= v[st2[-1]]:
            left2[st2[-1]] = i
            st2.pop()
        while st1 and v[i] >= v[st1[-1]]:
            left1[st1[-1]] = i
            aux.append(st1.pop())
        st1.append(i)
         while aux:
            st2.append(aux.pop())
   
    sol = 0
    for i in range(1, n+1):
        if left1[i] > 0:
            a = left1[i] - left2[i]
            b = right1[i] - i
            sol += multiply(a, b, v[i], v[left1[i]])
        if right1[i] < n + 1:
            a = i - left1[i]
            b = right2[i] - right1[i]
            sol += multiply(a, b, v[i], v[right1[i]])
   
    sol %= mod
    print(sol)


     return suma_arii
if __name__ == "__main__":
     main()


</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 22:15, 22 March 2024

Cerinta[edit | edit source]

Se consideră un șir de N numere naturale. Numim rectangle-sequence orice secvență continuă din șir (formată din elemente situate pe poziții consecutive) care conține cel puțin două elemente. Fiecare rectangle-sequence este caracterizată de un dreptunghi cu lungimile laturilor egale cu cele mai mari două elemente din cadrul ei.

Cerința[edit | edit source]

Să se calculeze restul împărțirii sumei ariilor dreptunghiurilor ce caracterizează toate rectangle-sequences din șir la numărul 1.000.000.007.

Date de intrare[edit | edit source]

Prima linie contine numărul natural nenul N, reprezentând numărul elementelor din șir, iar linia a doua conține, separate prin câte un spațiu, cele N elemente. Întrucât volumul datelor de intrare este foarte mare, vă recomandăm, în cazul în care folosiți pentru citire biblioteca iostream din standardul C++, să adaugați la începutul funcției main urmatoarele instrucțiuni:

std :: iosbase :: sync_with_stdio (false);
std :: cin.tie(0);

Date de ieșire[edit | edit source]

Ieșirea conține numărul de determinat, modulo 1.000.000.007. Î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 ≤ 1.000.000
  • 1 ≤ orice element din șir 1 ≤ 1.000.000.000
  • Subtask 1 (13 puncte): N ≤ 2000
  • Subtask 2 (23 puncte): N ≤ 100.000 și există cel mult 100 de numere distincte în șir.
  • Subtask 3 (27 puncte): N ≤ 200.000
  • Subtask 4 (37 puncte): nu există restricții suplimentare

Exemplul 1:[edit | edit source]

Intrare

3
2 3 1

Ieșire

15

Explicație[edit | edit source]

Sunt 3 rectangle-sequences: (2; 3); (2; 3; 1); (3; 1). Ariile celor trei deptunghiuri ce le caracterizează sunt: 6, 6, 3.

Exemplul 2:[edit | edit source]

Intrare

100000000000
2 3 1

Ieșire

Datele nu corespund restrictiilor impuse

Rezolvare[edit | edit source]

<syntaxhighlight lang="python3" line="1"> MaxN = 1000010 mod = 10**9 + 7

v = [0] * MaxN left1 = [0] * MaxN left2 = [0] * MaxN right1 = [0] * MaxN right2 = [0] * MaxN

def multiply(a, b, c, d):

   return ((a * b) % mod) * ((c * d) % mod) % mod

def citeste_si_verifica_elemente(n):

   print(f"Introduceți {n} elemente (fiecare urmat de Enter):")
   v_temp = []
   for i in range(1, n + 1):
       try:
           x = int(input(f"Elementul {i}: "))
           if not (1 <= x <= 10**9):
               print("Datele nu corespund restricțiilor impuse")
               return None
           v_temp.append(x)
       except ValueError:
           print("Datele nu corespund restricțiilor impuse")
           return None
   return v_temp

def main():

   try:
       n = int(input("Introduceți lungimea șirului: "))
       if not (1 <= n <= 10**6):
           print("Datele nu corespund restricțiilor impuse")
           return
   except ValueError:
       print("Datele nu corespund restricțiilor impuse")
       return
   
   v_input = citeste_si_verifica_elemente(n)
   if v_input is None:
       return
   
   v[1:n+1] = v_input
   for i in range(1, n+1):
       left1[i] = left2[i] = 0
       right1[i] = right2[i] = n + 1
   
   st1, st2, aux = [], [], []
   for i in range(1, n+1):
       while st2 and v[i] > v[st2[-1]]:
           right2[st2[-1]] = i
           st2.pop()
       while st1 and v[i] > v[st1[-1]]:
           right1[st1[-1]] = i
           aux.append(st1.pop())
       st1.append(i)
       while aux:
           st2.append(aux.pop())
   
   st1.clear()
   st2.clear()
   
   for i in range(n, 0, -1):
       while st2 and v[i] >= v[st2[-1]]:
           left2[st2[-1]] = i
           st2.pop()
       while st1 and v[i] >= v[st1[-1]]:
           left1[st1[-1]] = i
           aux.append(st1.pop())
       st1.append(i)
       while aux:
           st2.append(aux.pop())
   
   sol = 0
   for i in range(1, n+1):
       if left1[i] > 0:
           a = left1[i] - left2[i]
           b = right1[i] - i
           sol += multiply(a, b, v[i], v[left1[i]])
       if right1[i] < n + 1:
           a = i - left1[i]
           b = right2[i] - right1[i]
           sol += multiply(a, b, v[i], v[right1[i]])
   
   sol %= mod
   print(sol)

if __name__ == "__main__":

   main()

</syntaxhighlight>