#include <cstdio> #include <vector> #include <algorithm> using namespace std; int main() { int n, m, i, j, k; char c; scanf("%d", &n); vector<int> oszczednosci(n, 0); for (i = 0; i < n; ++i) scanf("%d", &oszczednosci[i]); scanf("%d%c", &m, &c); vector<int> zmiana(m, 0); for (i = 0; i < m; ++i) { scanf("%c", &c); if (c == 'W') zmiana[i] = 1; else zmiana[i] = -1; } vector<vector<int> > cykle; vector<bool> na_cyklu(m, false); for (i = 0; i < m; ++i) if (!na_cyklu[i]) { int nr_cyklu = cykle.size(); vector<int> nowy_cykl; j = i; do { nowy_cykl.push_back(j); na_cyklu[j] = true; j = (j + n % m) % m; } while (j != i); cykle.push_back(nowy_cykl); } vector<long long> liczba_serii_do_braku_pieniedzy(n, 0); for (i = 0; i < cykle.size(); ++i) { vector<int> wartosc(2 * cykle[i].size() + 1, 0); for (j = 0; j < cykle[i].size(); ++j) wartosc[j + 1] = wartosc[j] + zmiana[cykle[i][j]]; for (j = 0; j < cykle[i].size(); ++j) wartosc[cykle[i].size() + j + 1] = wartosc[cykle[i].size() + j] + zmiana[cykle[i][j]]; int minimum = 0; int maximum = 0; for (j = 0; j <= 2 * cykle[i].size(); ++j) { minimum = min(minimum, wartosc[j]); maximum = max(maximum, wartosc[j]); } vector<vector<int> > pozycje(maximum - minimum + 1, vector<int>()); vector<int> num(maximum - minimum + 1, 0); int roznica = -minimum; for (j = 0; j <= 2 * cykle[i].size(); ++j) pozycje[wartosc[j] + roznica].push_back(j); minimum = 0; for (j = 0; j <= cykle[i].size(); ++j) minimum = min(minimum, wartosc[j]); for (j = 0; j < cykle[i].size(); ++j) { int zmiana_na_okres = wartosc[j + cykle[i].size()] - wartosc[j]; if (num[minimum + roznica] >= pozycje[minimum + roznica].size() || pozycje[minimum + roznica][num[minimum + roznica]] > j + cykle[i].size()) minimum = wartosc[j]; minimum = min(minimum, wartosc[j + cykle[i].size()]); int najwiekszy_spadek = wartosc[j] - minimum; for (k = cykle[i][j]; k < n; k += m) { if (oszczednosci[k] > najwiekszy_spadek && zmiana_na_okres >= 0) liczba_serii_do_braku_pieniedzy[k] = -1; else { if (oszczednosci[k] > najwiekszy_spadek) { long long ile_okresow = (oszczednosci[k] - najwiekszy_spadek) / (-zmiana_na_okres); if ((oszczednosci[k] - najwiekszy_spadek) % (-zmiana_na_okres) != 0) ile_okresow++; oszczednosci[k] -= ile_okresow * (-zmiana_na_okres); liczba_serii_do_braku_pieniedzy[k] += ile_okresow * cykle[i].size(); } int wartosc_ostatniej = wartosc[j] - oszczednosci[k] + roznica; liczba_serii_do_braku_pieniedzy[k] += pozycje[wartosc_ostatniej][num[wartosc_ostatniej]] - j; } } num[wartosc[j] + roznica]++; } } long long wynik = -1; for (i = 0; i < n; ++i) if (liczba_serii_do_braku_pieniedzy[i] != -1) { if (wynik == -1) wynik = (liczba_serii_do_braku_pieniedzy[i] - 1) * n + i + 1; else wynik = min(wynik, (liczba_serii_do_braku_pieniedzy[i] - 1) * n + i + 1); } printf("%lld", wynik); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | #include <cstdio> #include <vector> #include <algorithm> using namespace std; int main() { int n, m, i, j, k; char c; scanf("%d", &n); vector<int> oszczednosci(n, 0); for (i = 0; i < n; ++i) scanf("%d", &oszczednosci[i]); scanf("%d%c", &m, &c); vector<int> zmiana(m, 0); for (i = 0; i < m; ++i) { scanf("%c", &c); if (c == 'W') zmiana[i] = 1; else zmiana[i] = -1; } vector<vector<int> > cykle; vector<bool> na_cyklu(m, false); for (i = 0; i < m; ++i) if (!na_cyklu[i]) { int nr_cyklu = cykle.size(); vector<int> nowy_cykl; j = i; do { nowy_cykl.push_back(j); na_cyklu[j] = true; j = (j + n % m) % m; } while (j != i); cykle.push_back(nowy_cykl); } vector<long long> liczba_serii_do_braku_pieniedzy(n, 0); for (i = 0; i < cykle.size(); ++i) { vector<int> wartosc(2 * cykle[i].size() + 1, 0); for (j = 0; j < cykle[i].size(); ++j) wartosc[j + 1] = wartosc[j] + zmiana[cykle[i][j]]; for (j = 0; j < cykle[i].size(); ++j) wartosc[cykle[i].size() + j + 1] = wartosc[cykle[i].size() + j] + zmiana[cykle[i][j]]; int minimum = 0; int maximum = 0; for (j = 0; j <= 2 * cykle[i].size(); ++j) { minimum = min(minimum, wartosc[j]); maximum = max(maximum, wartosc[j]); } vector<vector<int> > pozycje(maximum - minimum + 1, vector<int>()); vector<int> num(maximum - minimum + 1, 0); int roznica = -minimum; for (j = 0; j <= 2 * cykle[i].size(); ++j) pozycje[wartosc[j] + roznica].push_back(j); minimum = 0; for (j = 0; j <= cykle[i].size(); ++j) minimum = min(minimum, wartosc[j]); for (j = 0; j < cykle[i].size(); ++j) { int zmiana_na_okres = wartosc[j + cykle[i].size()] - wartosc[j]; if (num[minimum + roznica] >= pozycje[minimum + roznica].size() || pozycje[minimum + roznica][num[minimum + roznica]] > j + cykle[i].size()) minimum = wartosc[j]; minimum = min(minimum, wartosc[j + cykle[i].size()]); int najwiekszy_spadek = wartosc[j] - minimum; for (k = cykle[i][j]; k < n; k += m) { if (oszczednosci[k] > najwiekszy_spadek && zmiana_na_okres >= 0) liczba_serii_do_braku_pieniedzy[k] = -1; else { if (oszczednosci[k] > najwiekszy_spadek) { long long ile_okresow = (oszczednosci[k] - najwiekszy_spadek) / (-zmiana_na_okres); if ((oszczednosci[k] - najwiekszy_spadek) % (-zmiana_na_okres) != 0) ile_okresow++; oszczednosci[k] -= ile_okresow * (-zmiana_na_okres); liczba_serii_do_braku_pieniedzy[k] += ile_okresow * cykle[i].size(); } int wartosc_ostatniej = wartosc[j] - oszczednosci[k] + roznica; liczba_serii_do_braku_pieniedzy[k] += pozycje[wartosc_ostatniej][num[wartosc_ostatniej]] - j; } } num[wartosc[j] + roznica]++; } } long long wynik = -1; for (i = 0; i < n; ++i) if (liczba_serii_do_braku_pieniedzy[i] != -1) { if (wynik == -1) wynik = (liczba_serii_do_braku_pieniedzy[i] - 1) * n + i + 1; else wynik = min(wynik, (liczba_serii_do_braku_pieniedzy[i] - 1) * n + i + 1); } printf("%lld", wynik); return 0; } |