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
// clang-format off
#include<bits/stdc++.h>
using namespace std;
using LL=long long;
#define FOR(i,l,r) for(auto i=(l);i<=(r);++i)
#define REP(i,n) FOR(i,0,(n)-1)
#define ssize(x) int(x.size())
auto operator<<(ostream&o,auto p)->decltype(p.first,o){return o<<"("<<p.first<<", "<<p.second<<")";}
auto operator<<(ostream&o,auto x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<(", ")+2*!i++<<e;return o<<"}";}
#ifdef DEBUG
#define debug(x...) cerr<<"["#x"]: ",[](auto...$){((cerr<<$<<"; "),...);}(x),cerr<<'\n'
#else
#define debug(...) {}
#endif
// clang-format on

int
main()
{
    cin.tie(0)->sync_with_stdio(0);
    string A, B, C;
    cin >> A >> B >> C;
    reverse(A.begin(), A.end());
    reverse(B.begin(), B.end());
    reverse(C.begin(), C.end());

    int N = ssize(A);
    vector<bool> needs_carry(N), gives_carry(N), wrong(N);
    REP (i, N) {
        int a = A[i] - '0', b = B[i] - '0', c = C[i] - '0';
        needs_carry[i]  = ((a + b + 1) % 10 == c);
        gives_carry[i] = (a + b + (needs_carry[i] ? 1 : 0) >= 10);
        wrong[i] = !needs_carry[i] && ((a + b) % 10 != c);
    }
    while (N > 0 && (gives_carry[N - 1] || wrong[N - 1])) --N;

    LL score = 0;
    int cnt = 0;
    REP (begin, ssize(A)) {
        if (needs_carry[begin] || wrong[begin]) {
            cnt = 0;
            continue;
        }

        int blk_last = begin;
        while (gives_carry[blk_last] && needs_carry[blk_last + 1]) blk_last += 1;
        begin = blk_last;
        if (gives_carry[blk_last]) {
            cnt = 0;
            continue;
        }
        cnt += 1;
        score += cnt;
    }
    cout << score << "\n";
    return 0;
}