#include <cstdio>
#include <algorithm>
#include <functional>
using std::printf;
using std::scanf;
using std::lower_bound;
using std::greater;
using std::min;
const int MAX = 1000000;
int n;
int friends[MAX];
int m;
char wins[MAX + 1];
int cyclePos[MAX];
int cycleStart[MAX];
int accumulatedMin[MAX];
int accumulatedSum[MAX];
int values[MAX];
bool visited[MAX] = { 0 };
int cycleLength;
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", friends + i);
scanf("%d", &m);
scanf("%s", wins);
int accumulatedMinI = 0;
for (int wi = 0; wi < m; wi++)
{
if (visited[wi])
continue;
int sum = 0;
int accumulatedMinVal = 10;
int wpos = wi;
cycleLength = 0;
int cycleStartI = accumulatedMinI;
do {
cyclePos[wpos] = cycleLength;
cycleStart[wpos] = cycleStartI;
int val = wins[wpos] == 'W' ? 1 : -1;
sum += val;
accumulatedSum[accumulatedMinI] = sum;
values[accumulatedMinI] = val;
if (sum < accumulatedMinVal)
accumulatedMinVal = sum;
accumulatedMin[accumulatedMinI++] = accumulatedMinVal;
cycleLength++;
visited[wpos] = true;
wpos = (wpos + n) % m;
} while (wpos != wi);
}
long long failIndex = -1;
for (int fi = 0; fi < n; fi++)
{
int cPos = cyclePos[fi % m];
int cStart = cycleStart[fi % m];
int * aSum = accumulatedSum + cStart;
int cSum = aSum[cycleLength - 1];
int * aMin = accumulatedMin + cStart;
int * aValues = values + cStart;
int fCash = friends[fi];
int minDiffToEnd;
if (cPos == 0)
minDiffToEnd = aMin[cycleLength - 1];
else
minDiffToEnd = aMin[cycleLength - 1] - aMin[cPos] + aValues[cPos];
int minDiffFromStart;
if (cPos == 0)
minDiffFromStart = 0;
else
minDiffFromStart = aMin[cPos - 1];
int sumToEnd;
if (cPos == 0)
sumToEnd = aSum[cycleLength - 1];
else
sumToEnd = aSum[cycleLength - 1] - aSum[cPos - 1];
int minDiff = min(minDiffToEnd, sumToEnd + minDiffFromStart);
long long currentFailIndex = fi + 1;
if (fCash + minDiff > 0)
{
if (cSum >= 0)
continue;
int cyclesMissed = (fCash + minDiff) / (-cSum);
fCash += cSum * cyclesMissed;
currentFailIndex += (long long)cyclesMissed * cycleLength * n;
}
if (fCash + minDiffToEnd <= 0)
{
int previuosCash = cPos == 0 ? 0 : aMin[cPos] - aSum[cPos];
int * found = lower_bound(aMin + cPos, aMin + cycleLength, -fCash + previuosCash, greater<int>());
int posDiff = found - (aMin + cPos);
currentFailIndex += (long long)posDiff * n;
if (failIndex == -1 || currentFailIndex < failIndex)
failIndex = currentFailIndex;
continue;
}
fCash += sumToEnd;
currentFailIndex += (long long)(cycleLength - cPos) * n;
int * found = lower_bound(aMin, aMin + cPos, -fCash, greater<int>());
int posDiff = found - aMin;
currentFailIndex += (long long)posDiff * n;
if (failIndex == -1 || currentFailIndex < failIndex)
failIndex = currentFailIndex;
}
printf("%lld\n", failIndex);
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 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 | #include <cstdio> #include <algorithm> #include <functional> using std::printf; using std::scanf; using std::lower_bound; using std::greater; using std::min; const int MAX = 1000000; int n; int friends[MAX]; int m; char wins[MAX + 1]; int cyclePos[MAX]; int cycleStart[MAX]; int accumulatedMin[MAX]; int accumulatedSum[MAX]; int values[MAX]; bool visited[MAX] = { 0 }; int cycleLength; int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", friends + i); scanf("%d", &m); scanf("%s", wins); int accumulatedMinI = 0; for (int wi = 0; wi < m; wi++) { if (visited[wi]) continue; int sum = 0; int accumulatedMinVal = 10; int wpos = wi; cycleLength = 0; int cycleStartI = accumulatedMinI; do { cyclePos[wpos] = cycleLength; cycleStart[wpos] = cycleStartI; int val = wins[wpos] == 'W' ? 1 : -1; sum += val; accumulatedSum[accumulatedMinI] = sum; values[accumulatedMinI] = val; if (sum < accumulatedMinVal) accumulatedMinVal = sum; accumulatedMin[accumulatedMinI++] = accumulatedMinVal; cycleLength++; visited[wpos] = true; wpos = (wpos + n) % m; } while (wpos != wi); } long long failIndex = -1; for (int fi = 0; fi < n; fi++) { int cPos = cyclePos[fi % m]; int cStart = cycleStart[fi % m]; int * aSum = accumulatedSum + cStart; int cSum = aSum[cycleLength - 1]; int * aMin = accumulatedMin + cStart; int * aValues = values + cStart; int fCash = friends[fi]; int minDiffToEnd; if (cPos == 0) minDiffToEnd = aMin[cycleLength - 1]; else minDiffToEnd = aMin[cycleLength - 1] - aMin[cPos] + aValues[cPos]; int minDiffFromStart; if (cPos == 0) minDiffFromStart = 0; else minDiffFromStart = aMin[cPos - 1]; int sumToEnd; if (cPos == 0) sumToEnd = aSum[cycleLength - 1]; else sumToEnd = aSum[cycleLength - 1] - aSum[cPos - 1]; int minDiff = min(minDiffToEnd, sumToEnd + minDiffFromStart); long long currentFailIndex = fi + 1; if (fCash + minDiff > 0) { if (cSum >= 0) continue; int cyclesMissed = (fCash + minDiff) / (-cSum); fCash += cSum * cyclesMissed; currentFailIndex += (long long)cyclesMissed * cycleLength * n; } if (fCash + minDiffToEnd <= 0) { int previuosCash = cPos == 0 ? 0 : aMin[cPos] - aSum[cPos]; int * found = lower_bound(aMin + cPos, aMin + cycleLength, -fCash + previuosCash, greater<int>()); int posDiff = found - (aMin + cPos); currentFailIndex += (long long)posDiff * n; if (failIndex == -1 || currentFailIndex < failIndex) failIndex = currentFailIndex; continue; } fCash += sumToEnd; currentFailIndex += (long long)(cycleLength - cPos) * n; int * found = lower_bound(aMin, aMin + cPos, -fCash, greater<int>()); int posDiff = found - aMin; currentFailIndex += (long long)posDiff * n; if (failIndex == -1 || currentFailIndex < failIndex) failIndex = currentFailIndex; } printf("%lld\n", failIndex); return 0; } |
English