思路
首先,
相当于
因为如果 ,,对答案没有贡献。
然后, 相当于取 的前 位,这个手推一下就出来了。
所以,
相当于求 的前 位 的前 位 的前 位
将竖式列出来,就变成这样:
1
11
114
1145
11451
+ 114514
竖着看每一列,设 为 的第 位,第 列的和就为 。
我们发现,这不就是前缀和吗?
求出每一列的前缀和,一个一个从后往前进位即可。
代码
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <stack>
using namespace std;
char ch[500001];
int n, sum[500001];
stack<int> st;
int main(){
scanf("%s", ch + 1);
n = strlen(ch + 1);
for (int i = 1;i <= n;i ++) sum[i] = sum[i - 1] + (ch[i] ^ 48); // 前缀和
for (int i = n;i >= 1;i --){
sum[i - 1] += sum[i] / 10; // 进位
st.push(sum[i] % 10); // 当前位
}
st.push(sum[0]); // 如果进多了一位
while (st.size() && !st.top()) st.pop(); // 去掉前导 0
while (st.size()) printf("%d", st.top()), st.pop(); // 倒序输出
}