#include <cstdio>
#include <vector>
#include <map>
#include <algorithm>
#include <cassert>
#define ll long long
#define INF 1000000000000000001LL
using namespace std;
int a[1000000];
char cm[1000001];
struct {int cykl,pos,valpos,minto,minfrom;} cb[1000000];
struct cykl{int r,wm,pm,len; map<int,vector<int> > pozycje;
cykl():r(0),wm(1000001),pm(0),len(0) {}
};
vector<cykl> C;
void brut(int n, int m, char *cm) {
vector<int> b; b.resize(n);
for (int i=0;i<n;i++) b[i]=a[i];
ll ile=0;
int g=0,p=0;
while(1) {
ile++;
b[g] += (cm[p]=='W'?1:-1);
if (b[g]==0) break;
//else //printf("%d ",b[g]);
g=(g+1)%n;
p=(p+1)%m;
}
printf("brut: %lld g=%d p=%d\n",ile,g,p);
}
void rozklad(int n, int m, char *cm) {
int cn=0;
C.push_back(cykl());
for (int i=0;i<m;i++) {
if (cb[i].cykl==0) {
cn++; C.push_back(cykl());
int j=i,p=0;
while (cb[j].cykl==0) {
cb[j].cykl=cn;
cb[j].valpos=C[cn].r;
C[cn].r += (cm[j]=='W'?1:-1);
C[cn].pozycje[C[cn].r].push_back(p);
if (C[cn].r<C[cn].wm) {
C[cn].wm=C[cn].r;
C[cn].pm=p;
}
cb[j].minto=C[cn].wm;
cb[j].pos=p++;
j = (j+n)%m;
}
C[cn].len=p;
j=j-n; if (j<0) j+=m;
int wm=cb[j].valpos;
}
}
for (int i=1;i<C.size();i++) {
//printf("cykl=%d len=%d r=%d wm=%d pm=%d\n",i,C[i].len,C[i].r,C[i].wm,C[i].pm);
for (map<int,vector<int> >::iterator p=C[i].pozycje.begin();p!=C[i].pozycje.end();p++) {
//printf("%d: ",p->first);
for (int j=0;j<p->second.size();j++);
//printf("%d ",p->second[j]);
}
//printf("");
}
for (int i=0;i<m;i++); //printf("l=%d cykl=%d pos=%d valpos=%d\n",i,cb[i].cykl,cb[i].pos,cb[i].valpos);
}
int main() {
int n;
scanf("%d",&n);
for (int i=0;i<n;i++) scanf("%d",&a[i]);
int m;
scanf("%d\n",&m);
gets(cm);
//brut(n,m,cm);
rozklad(n,m,cm);
ll best=INF;int bestgn;
for (int i=0;i<n;i++) {
int pocz = i%m;
cykl &cy = C[cb[pocz].cykl];
int pos = cb[pocz].pos;
int spad = cb[pocz].valpos-cy.wm;
int spadpo = cy.pm-pos+1; if (spadpo<0) spadpo+=cy.len;
//printf("spad=%d po %d ",spad,spadpo);
ll dozera;
if (spad>=a[i]) {
int d = cb[pocz].valpos-a[i];
//printf("d=%d\n",d);
vector<int> &v = cy.pozycje[d];
assert(v.size()>0);
vector<int>::iterator it = lower_bound(v.begin(),v.end(),pos);
if (it!=v.end())
dozera=*it-pos;
else
dozera=pos-*v.begin()+cy.len;
} else if (cy.r>=0)
dozera=INF;
else {
ll ilec=((a[i]-spad-1)/(-cy.r)+1);
dozera = ilec*cy.len;
int d = cb[pocz].valpos-(a[i]+ilec*cy.r);
//printf("d=%d\n",d);
vector<int> &v = cy.pozycje[d];
vector<int>::iterator it = lower_bound(v.begin(),v.end(),pos);
if (it!=v.end())
dozera+=*it-pos;
else
dozera+=pos-*v.begin()+cy.len;
}
//printf("gracz %d dozera po %lld\n",i,dozera+1);
if (dozera<best) {best=dozera; bestgn=i;}
}
if (best==INF)
printf("-1\n");
else {
ll ans=(best)*n+bestgn+1;
printf("%lld\n",ans);
}
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 | #include <cstdio> #include <vector> #include <map> #include <algorithm> #include <cassert> #define ll long long #define INF 1000000000000000001LL using namespace std; int a[1000000]; char cm[1000001]; struct {int cykl,pos,valpos,minto,minfrom;} cb[1000000]; struct cykl{int r,wm,pm,len; map<int,vector<int> > pozycje; cykl():r(0),wm(1000001),pm(0),len(0) {} }; vector<cykl> C; void brut(int n, int m, char *cm) { vector<int> b; b.resize(n); for (int i=0;i<n;i++) b[i]=a[i]; ll ile=0; int g=0,p=0; while(1) { ile++; b[g] += (cm[p]=='W'?1:-1); if (b[g]==0) break; //else //printf("%d ",b[g]); g=(g+1)%n; p=(p+1)%m; } printf("brut: %lld g=%d p=%d\n",ile,g,p); } void rozklad(int n, int m, char *cm) { int cn=0; C.push_back(cykl()); for (int i=0;i<m;i++) { if (cb[i].cykl==0) { cn++; C.push_back(cykl()); int j=i,p=0; while (cb[j].cykl==0) { cb[j].cykl=cn; cb[j].valpos=C[cn].r; C[cn].r += (cm[j]=='W'?1:-1); C[cn].pozycje[C[cn].r].push_back(p); if (C[cn].r<C[cn].wm) { C[cn].wm=C[cn].r; C[cn].pm=p; } cb[j].minto=C[cn].wm; cb[j].pos=p++; j = (j+n)%m; } C[cn].len=p; j=j-n; if (j<0) j+=m; int wm=cb[j].valpos; } } for (int i=1;i<C.size();i++) { //printf("cykl=%d len=%d r=%d wm=%d pm=%d\n",i,C[i].len,C[i].r,C[i].wm,C[i].pm); for (map<int,vector<int> >::iterator p=C[i].pozycje.begin();p!=C[i].pozycje.end();p++) { //printf("%d: ",p->first); for (int j=0;j<p->second.size();j++); //printf("%d ",p->second[j]); } //printf(""); } for (int i=0;i<m;i++); //printf("l=%d cykl=%d pos=%d valpos=%d\n",i,cb[i].cykl,cb[i].pos,cb[i].valpos); } int main() { int n; scanf("%d",&n); for (int i=0;i<n;i++) scanf("%d",&a[i]); int m; scanf("%d\n",&m); gets(cm); //brut(n,m,cm); rozklad(n,m,cm); ll best=INF;int bestgn; for (int i=0;i<n;i++) { int pocz = i%m; cykl &cy = C[cb[pocz].cykl]; int pos = cb[pocz].pos; int spad = cb[pocz].valpos-cy.wm; int spadpo = cy.pm-pos+1; if (spadpo<0) spadpo+=cy.len; //printf("spad=%d po %d ",spad,spadpo); ll dozera; if (spad>=a[i]) { int d = cb[pocz].valpos-a[i]; //printf("d=%d\n",d); vector<int> &v = cy.pozycje[d]; assert(v.size()>0); vector<int>::iterator it = lower_bound(v.begin(),v.end(),pos); if (it!=v.end()) dozera=*it-pos; else dozera=pos-*v.begin()+cy.len; } else if (cy.r>=0) dozera=INF; else { ll ilec=((a[i]-spad-1)/(-cy.r)+1); dozera = ilec*cy.len; int d = cb[pocz].valpos-(a[i]+ilec*cy.r); //printf("d=%d\n",d); vector<int> &v = cy.pozycje[d]; vector<int>::iterator it = lower_bound(v.begin(),v.end(),pos); if (it!=v.end()) dozera+=*it-pos; else dozera+=pos-*v.begin()+cy.len; } //printf("gracz %d dozera po %lld\n",i,dozera+1); if (dozera<best) {best=dozera; bestgn=i;} } if (best==INF) printf("-1\n"); else { ll ans=(best)*n+bestgn+1; printf("%lld\n",ans); } return 0; } |
English