#define ll long long
#include <iostream>
#include <string>
using namespace std;
class BigInt {
ll length;
string prefix, suffix;
public:
// suffix is written backwards :)
BigInt(string p) { prefix = p; length = p.length(); suffix = "";}
char atIndex(int at) {
// 0 <= at < length
if (at < prefix.length()) {
return prefix[at];
} else if (at < (length - suffix.length())) {
return '0';
} else {
return suffix[length-at-1];
}
}
void incrementSuffix(int safeLength) {
for(int i = 0; i < suffix.length(); ++i) {
if (length - i - 1 < safeLength) {
// ALAAAARMM we try to edit chars which should be constant
suffix = "";
++length;
return;
}
if(suffix[i] < '9') {
suffix[i] = suffix[i] + 1;
return;
} else {
suffix[i] = '0';
}
}
// if we are here suffix was '999...999' or ''
suffix.append("1");
// check if sum of lengths
if (suffix.length() + prefix.length() > length) {
// try to increment old prefix if it doesn't collide with safeLength
int p = prefix.length()-1;
for (int i = p; i > safeLength; --i) {
if(prefix[i] < '9') {
prefix[i] += 1;
suffix[suffix.length() - 1 + i] = prefix[i];
return;
}
}
// it doesn't return so null suffix and make it longer
++length;
suffix = "";
}
}
// update bigint with new prefix. make sure it will be greater, return number of digits added to new_prefix
ll update(string new_prefix) {
if(length < new_prefix.length()) {
prefix = new_prefix;
length = prefix.length();
suffix = "";
return 0;
} else {
// compare new_prefix with prefix
// if it's greater: you can zero suffix, and keep the length. return number of filled zeroes (than prefix and sometimes suffix
// if it's same: increment suffix (make sure you can), keep the length, return length - len(prefix)
// if it's quicker: check if you can copy old, and increment suffix etc.
// if it's lower than: you have to increment length and zero suffix
for(int i = 0; i<length; ++i) {
// length is at least such long as new_prefix.length
char c = this->atIndex(i);
if (i < new_prefix.length()) {
if (c < new_prefix[i]) {
prefix = new_prefix;
suffix = "";
return length - new_prefix.length();
} else if (c > new_prefix[i]) {
++length;
suffix = "";
prefix = new_prefix;
return length - new_prefix.length();
}
} else {
// i is greater than new_prefix length and they were equal
// we can copy rest of prefix (maybe increment by one if len(prefix) == length and it's possible in other case fill with zeroes and increment suffix
// check if can increment suffix (if it doesn't collide with new_prefix)
// if not you have to increment length :(
this->incrementSuffix(new_prefix.length());
return length - new_prefix.length();
}
}
// they are equal!!!
++length;
suffix = "";
return length - new_prefix.length();
}
}
void print() {
for(int i=0; i<length; i++) {
cout<<this->atIndex(i);
}
cout<<endl;
}
};
int main() {
ios_base::sync_with_stdio(0);
ll res = 0;
int n;
cin>>n;
string s;
cin>>s;
BigInt* b = new BigInt(s);
// b->print();
for(int i = 1; i<n; i++) {
cin>>s;
res += b->update(s);
// b->print();
}
cout<<res<<endl;
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 | #define ll long long #include <iostream> #include <string> using namespace std; class BigInt { ll length; string prefix, suffix; public: // suffix is written backwards :) BigInt(string p) { prefix = p; length = p.length(); suffix = "";} char atIndex(int at) { // 0 <= at < length if (at < prefix.length()) { return prefix[at]; } else if (at < (length - suffix.length())) { return '0'; } else { return suffix[length-at-1]; } } void incrementSuffix(int safeLength) { for(int i = 0; i < suffix.length(); ++i) { if (length - i - 1 < safeLength) { // ALAAAARMM we try to edit chars which should be constant suffix = ""; ++length; return; } if(suffix[i] < '9') { suffix[i] = suffix[i] + 1; return; } else { suffix[i] = '0'; } } // if we are here suffix was '999...999' or '' suffix.append("1"); // check if sum of lengths if (suffix.length() + prefix.length() > length) { // try to increment old prefix if it doesn't collide with safeLength int p = prefix.length()-1; for (int i = p; i > safeLength; --i) { if(prefix[i] < '9') { prefix[i] += 1; suffix[suffix.length() - 1 + i] = prefix[i]; return; } } // it doesn't return so null suffix and make it longer ++length; suffix = ""; } } // update bigint with new prefix. make sure it will be greater, return number of digits added to new_prefix ll update(string new_prefix) { if(length < new_prefix.length()) { prefix = new_prefix; length = prefix.length(); suffix = ""; return 0; } else { // compare new_prefix with prefix // if it's greater: you can zero suffix, and keep the length. return number of filled zeroes (than prefix and sometimes suffix // if it's same: increment suffix (make sure you can), keep the length, return length - len(prefix) // if it's quicker: check if you can copy old, and increment suffix etc. // if it's lower than: you have to increment length and zero suffix for(int i = 0; i<length; ++i) { // length is at least such long as new_prefix.length char c = this->atIndex(i); if (i < new_prefix.length()) { if (c < new_prefix[i]) { prefix = new_prefix; suffix = ""; return length - new_prefix.length(); } else if (c > new_prefix[i]) { ++length; suffix = ""; prefix = new_prefix; return length - new_prefix.length(); } } else { // i is greater than new_prefix length and they were equal // we can copy rest of prefix (maybe increment by one if len(prefix) == length and it's possible in other case fill with zeroes and increment suffix // check if can increment suffix (if it doesn't collide with new_prefix) // if not you have to increment length :( this->incrementSuffix(new_prefix.length()); return length - new_prefix.length(); } } // they are equal!!! ++length; suffix = ""; return length - new_prefix.length(); } } void print() { for(int i=0; i<length; i++) { cout<<this->atIndex(i); } cout<<endl; } }; int main() { ios_base::sync_with_stdio(0); ll res = 0; int n; cin>>n; string s; cin>>s; BigInt* b = new BigInt(s); // b->print(); for(int i = 1; i<n; i++) { cin>>s; res += b->update(s); // b->print(); } cout<<res<<endl; return 0; } |
English