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
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
#define MAXN 1000007
typedef long long ll;
int tab[MAXN], cykl[MAXN], k, n, m, liczba_cykli, ktory[MAXN];
ll dlugosc_cyklu;
ll suma_cyklu[MAXN];
vector<int> cykle[MAXN];
vector<ll> sum[MAXN];
ll min_cyklu[MAXN];
vector<ll> lokalne_min[MAXN];
vector<bool> wrong[MAXN];
bool vis[MAXN];
void calc(int x) {
  vis[x] = true;
  cykl[x] = liczba_cykli;
  cykle[cykl[x]].push_back(x);
  if (!vis[(x + k)%m]){
    ktory[(x+k)%m] = ktory[x] + 1;
    calc((x + k)%m);
  }
}
void licz() {
  liczba_cykli = 0;
  for(int i = 0; i < m; i++) {
    if (!vis[i]){
      ktory[i] = 0;
      calc(i);
      liczba_cykli++;
    }
  }
  for(int i = 0; i < liczba_cykli; i++){ // cykle zaczynaja sie w 0, 1, 2, ...
    sum[i].push_back(tab[i]);
    for(int j = i + k; j != i; j = (j + k)%m) {
      sum[i].push_back(sum[i].back() + tab[j]);
    }
    suma_cyklu[i] = sum[i].back();
  }
}
// kod do rmq z naszej biblioteczki na swerca 2014 (epfl)
const int LOGN = 21;
//int rm[LOGN][N]; // rm[k][i] = min(tab[i], ..., tab[i + 2^k - 1])
vector<vector<int> > rm[MAXN];
void init (int nr_cyklu) { // tab[0..n-1]
    vector<int> empty;
    rm[nr_cyklu].push_back(empty);
    int n = sum[nr_cyklu].size();
    for(int i = 0; i < n; i++)
        rm[nr_cyklu][0].push_back(sum[nr_cyklu][i]);
    for(int my_k = 1; my_k < LOGN; my_k++){
        rm[nr_cyklu].push_back(empty);
        for(int i = 0; i <= n-(1<<my_k); i++)
            rm[nr_cyklu].back().push_back(min(rm[nr_cyklu][my_k-1][i],
                        rm[nr_cyklu][my_k-1][i +(1<<(my_k-1))]));
    }
}
int query (int nr_cyklu, int a, int b) { // a <= b or get a segfault!
//    printf("querying %d %d %d\n", nr_cyklu, a, b);
    int my_k = 31 - __builtin_clz(b-a+1);
//    printf("my_k %d rm size %d rm inner size %d\n", my_k, rm[nr_cyklu].size(), rm[nr_cyklu][my_k].size());
    return min(rm[nr_cyklu][my_k][a], rm[nr_cyklu][my_k][b-(1<<my_k)+1]);
}

int getMinSum(int nr_cyklu, int start, int end) {
  return query(nr_cyklu, start, end);
}

void szukajMinimow() {
  for(int i = 0; i < liczba_cykli; i++){
    for(int j = 0; j < dlugosc_cyklu; j++) {
        lokalne_min[i].push_back(getMinSum(i, j, j + dlugosc_cyklu - 1));
        if (j > 0)
            lokalne_min[i].back() -= sum[i][j-1];
    }
  }
}

void dorobKopie() {
  for(int i = 0; i < liczba_cykli; i++) {
    for(int j = 0; j < dlugosc_cyklu; j++) {
        sum[i].push_back(sum[i].back() + tab[(i+(ll)(k)*(ll)(j))%m]);
    }
  }
}

int ileKrokow(int nr_cyklu, int start, ll ile) {
  // ile krokow trzeba wykonac, zeby suma wynosila ile, zaczynajac od start
  int lowb = -1, upb = sum[nr_cyklu].size() - start - 1;
  // polowa tego powinna wystarczyc
  if (start != 0) {
    ile += sum[nr_cyklu][start - 1];
  }
  while(lowb != upb - 1){
    int strz = (lowb + upb)/2;
    if (getMinSum(nr_cyklu, start, start + strz) <= ile)
      upb = strz;
    else lowb = strz;
  }
  return upb;
}
ll liczby[MAXN];
ll po_ilu_obrotach;
int main() {
  scanf("%d",&n);
  for(int i =0 ; i<n ;i++)
    scanf("%lld",&liczby[i]);
  scanf("%d",&m);
  k = n % m;
  for(int i = 0; i < m ;i++){
    char a;
    scanf(" %c", &a);
    if (a == 'W')
      tab[i] = 1;
    else
      tab[i] = -1;
  }

  licz();
  dlugosc_cyklu = cykle[0].size();
  dorobKopie();
  for(int i = 0; i < liczba_cykli; i++) {
      init(i);
  }
  szukajMinimow();
  ll result = 1000000000ll * 1000000000ll;

  ll obrotow;
  for(int i = 0; i < n; i++) {
    //if (i % 1000 == 43)
   //   printf("%d\n", i/1000);
    int starts = i%m;
    int numer_cyklu = cykl[starts];
    int ktory_na = ktory[starts];
    ll local = lokalne_min[numer_cyklu][ktory_na];
  //  printf("local %lld\n", local);
  //  printf("suma cyklu %lld\n", suma_cyklu[numer_cyklu]);
    if (local >= 0)
      continue;
    ll in_local = liczby[i] + local;
    if (in_local <= 0) {
      obrotow = 0ll;
    } else {
      if (suma_cyklu[numer_cyklu] >= 0)
        continue; //never
      obrotow = in_local / (-suma_cyklu[numer_cyklu]); // trzeba zrobic tyle obrotow + jakas niezerowa czesc obrotu (max 1.0)
      if (in_local % (-suma_cyklu[numer_cyklu]))
          obrotow++;
    }

    ll brakuje = liczby[i] + obrotow * suma_cyklu[numer_cyklu];

  //  printf("i %d, nr cyklu %d ktory %d local %lld in_local %lld obrotow %lld brakuje %lld\n", i, numer_cyklu, ktory_na, local, in_local, obrotow, brakuje);

    ll ruchow = ileKrokow(numer_cyklu, ktory_na, -brakuje);
  //  printf("dodatkowo %lld ruchow\n", ruchow);
   // printf("skonczy sie po %lld\n", obrotow * m * n + ruchow * n + (i+1));
    result = min(result, obrotow * dlugosc_cyklu * (ll)(n) + ruchow * n + (ll)(i+1));
  }
  if (result >= 1000000000ll * 1000000000ll)
    printf("-1\n");
  else
    printf("%lld\n", result);
}