#include<iostream> #include<cstdio> #include<vector> #include<deque> #include<algorithm> #include<limits> using namespace std; typedef long long ll; const ll infty = numeric_limits<long long>::max(); const int NM=1000000; int a[NM]; int cycles[NM]; ll howMany[NM]; int n_cycles; int cycle_len; int n,m; struct elem { vector<int> buddies; int delta; // +1 or -1 elem() {} } cycle[NM]; int nwd(int a, int b) { return b ? nwd(b, a % b) : a; } void getCycle(int a) { for(int i=0; i<cycle_len; ++i) { cycle[i].delta=cycles[a]; cycle[i].buddies.clear(); while(a < n) { cycle[i].buddies.push_back(a); a += m; } a= (a+n) % m; } } ll findDrop(int b, int d, int l) { if((b-d) % (-l) == 0) return (b-d)/(-l); return (b-d)/(-l) +1; } void processCycle() { deque<int> drops; int level=0; for(int i=0; i<cycle_len; ++i) { level+=cycle[i].delta; if(-level > (int)drops.size()) drops.push_back(i); } int first=0; int last=cycle_len-1; // cout << "["<<first << "," << last << "]" << endl; // cout << "initial drops" << endl; // for(int i=0; i<drops.size(); ++i) cout << drops[i] << " " ; // cout << endl; int curr_pos=0; for(int i=cycle_len-1; i>=0; --i) { // cout << "curr_poss " << curr_pos << ": " << cycle[curr_pos].buddies.size() << endl; for(auto bud : cycle[curr_pos].buddies) { int budget=a[bud]; // czy mozna zejsc do -budget ? : // cout << "dropsize=" << drops.size() << " budget=" << budget << endl; if(drops.size() >= budget) { howMany[bud]=drops[budget-1]-first+1; // cout << bud << ": " << howMany[bud] << endl; continue; } // nie mozna zejsc do -budget ale suma cyklu jest ujemna: if(level < 0) { // znajdz min k t.ze. budget - k(-level) <= drops.size ll k=findDrop(budget,drops.size(),level); howMany[bud]=k*cycle_len+(drops[budget-k*(-level)-1]-first+1); // cout << bud << ": drop : " << k << "," << howMany[bud] << endl; continue; } // ten koles nie ma szans stracic calej kasy: howMany[bud]=infty; // cout << bud << ": " << howMany[bud] << endl; } --first; --last; if(cycle[i].delta == -1) drops.push_front(first); else if (!drops.empty()) drops.pop_front(); if(!drops.empty() && drops.back() > last) drops.pop_back(); // cout << "drops next: "; // for(int i=0; i<drops.size(); ++i) cout << drops[i] << " "; // cout << endl; curr_pos=i; } } int main() { scanf("%d",&n); for(int i=0; i < n; ++i) scanf("%d",a+i); scanf("%d",&m); { char buf[NM + 4]; scanf("%s", buf); for(int i=0; i < m; ++i) cycles[i] = buf[i] =='W' ? 1 : -1; } //cout << "n= " << n << endl; //for(int i=0; i<n; ++i) cout << a[i] << " "; //cout << endl; //cout << "m= " << m << endl; //for(int i=0; i<m; ++i) cout << cycles[i] << " "; //cout << endl; n_cycles=nwd(m,n); cycle_len=m/n_cycles; for(int i=0; i<nwd(n,m); ++i) { getCycle(i); // w cycle laduje odpowiedni cykl // cout << "Cykl " << i << endl; // for(int i=0; i<cycle_len; ++i) { // cout << i << ": " << cycle[i].delta << endl; // cout << "buddies: "; // for(auto bud : cycle[i].buddies) cout << bud << ","; // cout << endl; // } processCycle(); // wylicza ile razy zagra koles z tego cyklu zanim zbankrutuje } // wynik: i=argmin(howMany), wynik=i+(min(howMany)*(n-1)) ll result=infty; for(int i=0; i<n; ++i) if(howMany[i] < infty) if(result > (howMany[i]-1)*n+i+1) result=(howMany[i]-1)*n+i+1; if(result==infty) printf("%d\n",-1); else printf("%lld\n",result); 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 129 130 131 132 133 134 135 136 137 138 139 140 141 | #include<iostream> #include<cstdio> #include<vector> #include<deque> #include<algorithm> #include<limits> using namespace std; typedef long long ll; const ll infty = numeric_limits<long long>::max(); const int NM=1000000; int a[NM]; int cycles[NM]; ll howMany[NM]; int n_cycles; int cycle_len; int n,m; struct elem { vector<int> buddies; int delta; // +1 or -1 elem() {} } cycle[NM]; int nwd(int a, int b) { return b ? nwd(b, a % b) : a; } void getCycle(int a) { for(int i=0; i<cycle_len; ++i) { cycle[i].delta=cycles[a]; cycle[i].buddies.clear(); while(a < n) { cycle[i].buddies.push_back(a); a += m; } a= (a+n) % m; } } ll findDrop(int b, int d, int l) { if((b-d) % (-l) == 0) return (b-d)/(-l); return (b-d)/(-l) +1; } void processCycle() { deque<int> drops; int level=0; for(int i=0; i<cycle_len; ++i) { level+=cycle[i].delta; if(-level > (int)drops.size()) drops.push_back(i); } int first=0; int last=cycle_len-1; // cout << "["<<first << "," << last << "]" << endl; // cout << "initial drops" << endl; // for(int i=0; i<drops.size(); ++i) cout << drops[i] << " " ; // cout << endl; int curr_pos=0; for(int i=cycle_len-1; i>=0; --i) { // cout << "curr_poss " << curr_pos << ": " << cycle[curr_pos].buddies.size() << endl; for(auto bud : cycle[curr_pos].buddies) { int budget=a[bud]; // czy mozna zejsc do -budget ? : // cout << "dropsize=" << drops.size() << " budget=" << budget << endl; if(drops.size() >= budget) { howMany[bud]=drops[budget-1]-first+1; // cout << bud << ": " << howMany[bud] << endl; continue; } // nie mozna zejsc do -budget ale suma cyklu jest ujemna: if(level < 0) { // znajdz min k t.ze. budget - k(-level) <= drops.size ll k=findDrop(budget,drops.size(),level); howMany[bud]=k*cycle_len+(drops[budget-k*(-level)-1]-first+1); // cout << bud << ": drop : " << k << "," << howMany[bud] << endl; continue; } // ten koles nie ma szans stracic calej kasy: howMany[bud]=infty; // cout << bud << ": " << howMany[bud] << endl; } --first; --last; if(cycle[i].delta == -1) drops.push_front(first); else if (!drops.empty()) drops.pop_front(); if(!drops.empty() && drops.back() > last) drops.pop_back(); // cout << "drops next: "; // for(int i=0; i<drops.size(); ++i) cout << drops[i] << " "; // cout << endl; curr_pos=i; } } int main() { scanf("%d",&n); for(int i=0; i < n; ++i) scanf("%d",a+i); scanf("%d",&m); { char buf[NM + 4]; scanf("%s", buf); for(int i=0; i < m; ++i) cycles[i] = buf[i] =='W' ? 1 : -1; } //cout << "n= " << n << endl; //for(int i=0; i<n; ++i) cout << a[i] << " "; //cout << endl; //cout << "m= " << m << endl; //for(int i=0; i<m; ++i) cout << cycles[i] << " "; //cout << endl; n_cycles=nwd(m,n); cycle_len=m/n_cycles; for(int i=0; i<nwd(n,m); ++i) { getCycle(i); // w cycle laduje odpowiedni cykl // cout << "Cykl " << i << endl; // for(int i=0; i<cycle_len; ++i) { // cout << i << ": " << cycle[i].delta << endl; // cout << "buddies: "; // for(auto bud : cycle[i].buddies) cout << bud << ","; // cout << endl; // } processCycle(); // wylicza ile razy zagra koles z tego cyklu zanim zbankrutuje } // wynik: i=argmin(howMany), wynik=i+(min(howMany)*(n-1)) ll result=infty; for(int i=0; i<n; ++i) if(howMany[i] < infty) if(result > (howMany[i]-1)*n+i+1) result=(howMany[i]-1)*n+i+1; if(result==infty) printf("%d\n",-1); else printf("%lld\n",result); return 0; } |