#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int duzo = 200007, malo = 15;
int ilema[duzo], iledod[duzo];
int pocz[duzo][malo], kon[duzo][malo];
int poprz[2 * malo];
int buduj_poprz(int i) {
int ind = 0;
for(int k = 0; k < ilema[i - 1]; ++k) {
poprz[ind] = pocz[i - 1][k];
++ind;
}
for(int k = iledod[i - 1] - 1; k >= 0; --k) {
poprz[ind] = kon[i - 1][k];
++ind;
}
return ind;
}
int laduj(int a, int i) {
stack<int> cyfry;
while(a > 0) {
cyfry.push(a % 10);
a /= 10;
}
int ilecyfr = 0;
while(!cyfry.empty()) {
pocz[i][ilecyfr] = cyfry.top();
cyfry.pop();
++ilecyfr;
}
ilema[i] = ilecyfr;
}
void dodaj1(int i) {
int c = 0;
while(kon[i - 1][c] == 9) {
kon[i - 1][c] = 0;
++c;
}
++kon[i - 1][c];
}
int ile_dod(int i) {
if(i == 1) return 0;
int ilecyfr = ilema[i], ilestary = ilema[i - 1] + iledod[i - 1];
int rowne = 0, dod, iledp = iledod[i - 1], ind, zmniejsz = 0;
if(iledp >= malo) {
for(int c = 0; c < min(ilecyfr, ilema[i - 1]) && !rowne; ++c) {
if(pocz[i - 1][c] < pocz[i][c]) rowne = -1;
else if(pocz[i - 1][c] > pocz[i][c]) rowne = 1;
}
if(ilecyfr > ilema[i - 1] && !rowne) rowne = -1;
}
else {
ind = buduj_poprz(i);
for(int c = 0; c < min(ilecyfr, ind) && !rowne; ++c) {
if(poprz[c] < pocz[i][c]) rowne = -1;
else if(poprz[c] > pocz[i][c]) rowne = 1;
}
}
if(rowne == -1) dod = max(ilestary - ilecyfr, 0);
else if(rowne == 1) dod = max(ilestary - ilecyfr + 1, 0);
else {
if(ilestary < ilecyfr) return 0;
dod = ilestary - ilecyfr;
if(iledp >= malo) {
dodaj1(i);
for(int k = ilecyfr; k < ilema[i - 1]; ++k) {
pocz[i][k] = pocz[i - 1][k];
++zmniejsz;
}
ilema[i] = max(ilema[i - 1], ilema[i]);
}
else {
ind = buduj_poprz(i);
int pierw = -1;
for(int k = ind - 1; k >= 0 && pierw == -1; --k) {
if(poprz[k] != 9) pierw = k;
}
if(pierw < ilecyfr) ++dod;
else {
++poprz[pierw];
for(int k = pierw + 1; k < ind; ++k) poprz[k] = 0;
for(int k = ind - 1, c = 0; c < dod; ++c) {
kon[i][c] = poprz[k];
--k;
}
for(int k = ilecyfr; k < ilema[i - 1]; ++k) {
pocz[i][k] = poprz[k];
++zmniejsz;
}
ilema[i] = max(ilema[i - 1], ilema[i]);
}
}
}
iledod[i] = dod - zmniejsz;
return dod;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int n, rob;
cin >> n;
ll wyn = 0;
for(int i = 1; i <= n; ++i) {
cin >> rob;
laduj(rob, i);
wyn += (ll)ile_dod(i);
}
cout << wyn;
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 | #include <bits/stdc++.h> using namespace std; typedef long long ll; const int duzo = 200007, malo = 15; int ilema[duzo], iledod[duzo]; int pocz[duzo][malo], kon[duzo][malo]; int poprz[2 * malo]; int buduj_poprz(int i) { int ind = 0; for(int k = 0; k < ilema[i - 1]; ++k) { poprz[ind] = pocz[i - 1][k]; ++ind; } for(int k = iledod[i - 1] - 1; k >= 0; --k) { poprz[ind] = kon[i - 1][k]; ++ind; } return ind; } int laduj(int a, int i) { stack<int> cyfry; while(a > 0) { cyfry.push(a % 10); a /= 10; } int ilecyfr = 0; while(!cyfry.empty()) { pocz[i][ilecyfr] = cyfry.top(); cyfry.pop(); ++ilecyfr; } ilema[i] = ilecyfr; } void dodaj1(int i) { int c = 0; while(kon[i - 1][c] == 9) { kon[i - 1][c] = 0; ++c; } ++kon[i - 1][c]; } int ile_dod(int i) { if(i == 1) return 0; int ilecyfr = ilema[i], ilestary = ilema[i - 1] + iledod[i - 1]; int rowne = 0, dod, iledp = iledod[i - 1], ind, zmniejsz = 0; if(iledp >= malo) { for(int c = 0; c < min(ilecyfr, ilema[i - 1]) && !rowne; ++c) { if(pocz[i - 1][c] < pocz[i][c]) rowne = -1; else if(pocz[i - 1][c] > pocz[i][c]) rowne = 1; } if(ilecyfr > ilema[i - 1] && !rowne) rowne = -1; } else { ind = buduj_poprz(i); for(int c = 0; c < min(ilecyfr, ind) && !rowne; ++c) { if(poprz[c] < pocz[i][c]) rowne = -1; else if(poprz[c] > pocz[i][c]) rowne = 1; } } if(rowne == -1) dod = max(ilestary - ilecyfr, 0); else if(rowne == 1) dod = max(ilestary - ilecyfr + 1, 0); else { if(ilestary < ilecyfr) return 0; dod = ilestary - ilecyfr; if(iledp >= malo) { dodaj1(i); for(int k = ilecyfr; k < ilema[i - 1]; ++k) { pocz[i][k] = pocz[i - 1][k]; ++zmniejsz; } ilema[i] = max(ilema[i - 1], ilema[i]); } else { ind = buduj_poprz(i); int pierw = -1; for(int k = ind - 1; k >= 0 && pierw == -1; --k) { if(poprz[k] != 9) pierw = k; } if(pierw < ilecyfr) ++dod; else { ++poprz[pierw]; for(int k = pierw + 1; k < ind; ++k) poprz[k] = 0; for(int k = ind - 1, c = 0; c < dod; ++c) { kon[i][c] = poprz[k]; --k; } for(int k = ilecyfr; k < ilema[i - 1]; ++k) { pocz[i][k] = poprz[k]; ++zmniejsz; } ilema[i] = max(ilema[i - 1], ilema[i]); } } } iledod[i] = dod - zmniejsz; return dod; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n, rob; cin >> n; ll wyn = 0; for(int i = 1; i <= n; ++i) { cin >> rob; laduj(rob, i); wyn += (ll)ile_dod(i); } cout << wyn; return 0; } |
English