Fermierul Feder cultivă cartofi pe un teren dreptunghiular de lățime N
metri și lungime M
metri, compartimentat în N * M
zone pătratice identice de lungime 1
metru, dispuse alăturat, câte N
pe lățime (pe N
linii, numerotate de la 1
la N
) și câte M
pe lungime (pe M
coloane, numerotate de la 1
la M
).
În fiecare zonă pătratică se află câte o plantă de cartofi. Parcurgând terenul de la prima linie către ultima, fiecare linie cu număr impar parcurgând-o de la coloana 1
către coloana M
, iar fiecare linie cu număr par parcurgând-o de la coloana M
către coloana 1
, fermierul (pasionat de matematică) a scris numerele cartofilor produși de fiecare plantă, în ordinea parcurgerii, și a constatat că a obținut șirul cifrelor unităților primilor N * M
termeni ai șirului Fibonacci (vezi Figura 1 în care N = 3
și M = 6
).
Cerința
Scrieți un program care citește numerele N
și M
(cu semnificația din enunț), iar apoi determină:
1. numărul plantelor din teren care nu au produs niciun cartof;
2. numărul maxim de cartofi care pot fi produși de plantele dintr-o suprafață pătratică din terenul fermierului;
3. pentru fiecare dintre cele Q
perechi de numere (A, B)
citite, numărul cartofilor produși de plantele aflate în zonele pătratice situate între coloanele cu numerele A
și B
, inclusiv acestea.
Date de intrare
Fișierul de intrare cartofi.in
conține pe prima linie un număr natural C
reprezentând cerința din problemă care trebuie rezolvată (1
, 2
sau 3
). A doua linie a fișierului conține cele două numere naturale N
și M
, separate printr-un spațiu, cu semnificația din enunț. Dacă C = 3
, atunci fișierul va mai conține pe a treia linie numărul natural Q
, iar pe fiecare linie dintre următoarele Q
, câte două numere naturale separate printr-un spațiu reprezentând câte o pereche de numere (A, B)
dintre cele Q
.
Date de ieșire
Fișierul de ieșire cartofi.out
va conține:
- Dacă
C = 1
, pe prima linie un număr natural reprezentând răspunsul la cerința1
. - Dacă
C = 2
, pe prima linie un număr natural reprezentând răspunsul la cerința2
. - Dacă
C = 3
,Q
linii, câte o linie pentru fiecare pereche(A, B)
dintre celeQ
. Linia corespunzătoare fiecărei perechi(A, B)
va conține un număr natural reprezentând numărul cartofilor produși de plantele aflate în zonele pătratice situate între coloanele cu numereleA
șiB
, inclusiv aceste valori, reprezentând răspunsul la cerința3
.
Restricții și precizări
2 ≤ N ≤ 500.000.000
3 ≤ M ≤ 1.000.000.000
N ≤ M
Q ≤ 100.000
1 ≤ A ≤ B ≤ M
- Pentru cerința 1 se acordă 20p, iar pentru cerințele 2 și 3 se acordă câte 40p.
- Șirul Fibonacci este definit astfel:
f(1) = 1
,f(2) = 1
șif(n) = f(n-1) + f(n-2)
, dacăn ≥ 3
, (n
este un număr natural nenul). - O suprafață pătratică din teren este formată din
K * K
zone pătratice alăturate dispuse câteK
pe linie și câteK
pe coloană, oricare ar fi1 ≤ K ≤ min{N, M}
.
Exemplul 1:
cartofi.in
1 3 6
cartofi.out
1
Explicație
Se rezolvă cerința 1. N = 3
, M = 6
. Primii N * M = 18
termeni ai șirului Fibonacci sunt: 1
, 1
, 2
, 3
, 5
, 8
, 13
, 21
, 34
, 55
, 89
, 144
, 233
, 377
, 610
, 987
, 1597
, 2584
. Astfel, numerele cartofilor produși de fiecare plantă din teren sunt cele din Figura 1. În teren există o singură plantă care nu a produs niciun cartof (cea din linia 3
, coloana 3
).
Exemplul 2:
cartofi.in
2 3 6
cartofi.out
42
Explicație
Se rezolvă cerința 2. N = 3
, M = 6
. Numerele cartofilor produși de fiecare plantă din teren sunt cele din tabelul din Figura 1. Plantele aflate în suprafața pătratică galbenă din tabelul din Figura 2 au produs cel mai mare număr de cartofi.
Exemplul 3:
cartofi.in
3 5 6 3 1 2 4 6 2 3
cartofi.out
48 64 43
Explicație
Se rezolvă cerința 3. N = 5
, M = 6
, Q = 3
. Tabelul din Figura 3 conține numerele cartofilor produși de fiecare plantă din teren sunt cele din Figura 3. Suma elementelor cuprinse între coloanele (1, 2)
, inclusiv 1
și 2
, este 48
. Suma elementelor cuprinse între coloanele (4, 6)
, inclusiv 4
și 6
, este 64
. Suma elementelor cuprinse între coloanele (2, 3)
, inclusiv 2
și 3
, este 43
.
#include <bits/stdc++.h> using namespace std; ifstream f("cartofi.in"); ofstream g("cartofi.out"); pair<int, int> fibo(long long n) { if (n == 0) return {0, 1}; auto p = fibo(n >> 1ll); int ax = ((p.second << 1) - p.first + 10) % 10; int c = (p.first * ax) % 10; int d = (p.first * p.first + p.second * p.second) % 10; if (n & 1) return {d, (c + d) % 10}; return {c, d}; } int n, m; long long cols[61]; long long query(int); void build(); void solve1(); void solve2(); void solve3(); int32_t main() { int task; f >> task >> n >> m; if (task == 1) solve1(); else if (task == 2) solve2(); else solve3(); return 0; } void solve1() { long long ct = 0, ax = (1ll * n * m) / 60ll, ap = (1ll * n * m) % 60ll; long long rez = 0; for (int i = 0, a = 0, b = 1, c; i < 60; i++) { ct += !b; if (i < ap) rez += !b; c = (a + b) % 10; a = b; b = c; } rez += 1ll * ax * ct; g << rez; } void solve2() { build(); long long rez = 0, ax; for (int i = n; i <= min(n + 60, m); i++) { ax = query(i) - query(i - n); rez = max(rez, ax); } g << rez; } void solve3() { build(); int q, st, dr; for (f >> q; q; q--) { f >> st >> dr; g << (long long)query(dr) - query(st - 1) << '\n'; } } void build() { long long aux[61], prv = 0, md = n % 60, ct = n / 60, ind; memset(aux, 0, sizeof aux); for (int i = 0, nr; i < min(n, 60); i++, prv += m) for (int j = 1; j <= min(m, 60); j++) { ind = prv; if (i & 1) ind += m - j + 1; else ind += j; nr = fibo(ind).first; cols[j] += nr; if (i < md) aux[j] += nr; } for (int i = 1; i <= min(m, 60); i++) cols[i] = 1ll * cols[i] * ct + aux[i], cols[i] += cols[i - 1]; } long long query(int poz) { long long rez = 1ll * (poz / 60) * cols[60]; rez += cols[poz % 60]; return rez; }