// PA2026, @mjm, r3c-dod
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
using lol = long long;
int nextInt() { int n; scanf("%d", &n); return n; }
lol nextLol() { lol n; scanf("%lld", &n); return n; }
inline lol myMax(lol a, lol b) { return a >= b ? a : b; }
inline int myMin(int a, int b) { return a <= b ? a : b; }
const int N = 1000000 + 9;
char aa[N];
char bb[N];
char cc[N];
int a[N];
int b[N];
pair<int, int> checkBlock(int i) {
// returns: (len, nextI)
// len := len of correct block, or -1
// nextI := next index i, where to continue
if (i < 0)
return { -1 , -1 };
if (a[i] == b[i])
return { 1, i - 1 };
if (a[i] != 10 + b[i])
return { -1, i - 1 };
int len = 1;
while (i > 0) {
--i;
++len;
if (a[i] + 1 == b[i])
return { len, i - 1 };
if (a[i] + 1 != 10 + b[i])
return { -1, i };
if (i == 0)
return { -1, i - 1 };
}
return { -1, i - 1 };
}
lol solve() {
int n;
for (n = 0; aa[n]; ++n) {
a[n] = aa[n] - '0' + bb[n] - '0';
b[n] = cc[n] - '0';
}
lol res = 0;
for (int i = n - 1; i >= 0; ) {
if (a[i] != b[i] && a[i] != 10 + b[i]) {
--i;
continue;
}
int blockCount = 0;
while (true) {
pair<int, int> p = checkBlock(i);
int mem = i;
i = p.second;
if (p.first < 0)
break;
//printf("next block: i: %d len: %d\n", mem, p.first);
++blockCount;
}
//printf(" BLOCK COUNT: %d\n", blockCount);
res += 1LL * blockCount * (blockCount + 1);
}
res /= 2;
return res;
}
lol brute() {
int n = 0;
while (aa[n]) ++n;
lol res = 0;
for (int i = 0; i < n; ++i) {
for (int j = i; j < n; ++j) {
lol a = 0;
lol b = 0;
lol c = 0;
for (int k = i; k <= j; ++k) {
a = 10 * a + aa[k] - '0';
b = 10 * b + bb[k] - '0';
c = 10 * c + cc[k] - '0';
}
if (a + b == c) {
//printf("brute found %d %d\n", i, j);
++res;
}
}
}
return res;
}
int main() {
scanf("%s%s%s", aa, bb, cc);
if (false) {
sprintf(aa, "55555");
bb[5] = cc[5] = 0;
for (int b = 50000; b < 100000; ++b) {
if (b % 1000 == 999) printf("next b: %d\n", b);
for (int c = 0; c < 100000; ++c) {
int x;
x = b;
for (int i = 4; i >= 0; --i) {
bb[i] = '0' + (x % 10); x /= 10;
}
x = c;
for (int i = 4; i >= 0; --i) {
cc[i] = '0' + (x % 10); x /= 10;
}
lol bru = brute();
lol res = solve();
if (bru != res) {
printf("%s %s %s => %lld %lld\n", aa, bb, cc, bru, res);
}
}
}
lol bru = brute();
}
lol res = solve();
printf("%lld\n", res);
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 | // PA2026, @mjm, r3c-dod #include <cstdio> #include <cmath> #include <vector> #include <queue> using namespace std; using lol = long long; int nextInt() { int n; scanf("%d", &n); return n; } lol nextLol() { lol n; scanf("%lld", &n); return n; } inline lol myMax(lol a, lol b) { return a >= b ? a : b; } inline int myMin(int a, int b) { return a <= b ? a : b; } const int N = 1000000 + 9; char aa[N]; char bb[N]; char cc[N]; int a[N]; int b[N]; pair<int, int> checkBlock(int i) { // returns: (len, nextI) // len := len of correct block, or -1 // nextI := next index i, where to continue if (i < 0) return { -1 , -1 }; if (a[i] == b[i]) return { 1, i - 1 }; if (a[i] != 10 + b[i]) return { -1, i - 1 }; int len = 1; while (i > 0) { --i; ++len; if (a[i] + 1 == b[i]) return { len, i - 1 }; if (a[i] + 1 != 10 + b[i]) return { -1, i }; if (i == 0) return { -1, i - 1 }; } return { -1, i - 1 }; } lol solve() { int n; for (n = 0; aa[n]; ++n) { a[n] = aa[n] - '0' + bb[n] - '0'; b[n] = cc[n] - '0'; } lol res = 0; for (int i = n - 1; i >= 0; ) { if (a[i] != b[i] && a[i] != 10 + b[i]) { --i; continue; } int blockCount = 0; while (true) { pair<int, int> p = checkBlock(i); int mem = i; i = p.second; if (p.first < 0) break; //printf("next block: i: %d len: %d\n", mem, p.first); ++blockCount; } //printf(" BLOCK COUNT: %d\n", blockCount); res += 1LL * blockCount * (blockCount + 1); } res /= 2; return res; } lol brute() { int n = 0; while (aa[n]) ++n; lol res = 0; for (int i = 0; i < n; ++i) { for (int j = i; j < n; ++j) { lol a = 0; lol b = 0; lol c = 0; for (int k = i; k <= j; ++k) { a = 10 * a + aa[k] - '0'; b = 10 * b + bb[k] - '0'; c = 10 * c + cc[k] - '0'; } if (a + b == c) { //printf("brute found %d %d\n", i, j); ++res; } } } return res; } int main() { scanf("%s%s%s", aa, bb, cc); if (false) { sprintf(aa, "55555"); bb[5] = cc[5] = 0; for (int b = 50000; b < 100000; ++b) { if (b % 1000 == 999) printf("next b: %d\n", b); for (int c = 0; c < 100000; ++c) { int x; x = b; for (int i = 4; i >= 0; --i) { bb[i] = '0' + (x % 10); x /= 10; } x = c; for (int i = 4; i >= 0; --i) { cc[i] = '0' + (x % 10); x /= 10; } lol bru = brute(); lol res = solve(); if (bru != res) { printf("%s %s %s => %lld %lld\n", aa, bb, cc, bru, res); } } } lol bru = brute(); } lol res = solve(); printf("%lld\n", res); return 0; } |
English