Divide by Zero 2021 and Codeforces Round #714 (Div. 2)
C Add One
看大佬都是打表做的,是因为操作的数据范围不大
看题意,每一位增加1不会进位到下一位,而是在前面直接增加一个1,所以我们可以直接对每个数组操作m次后看它会变成几位
在我们观察来看,只有当该位为9的时候,把他加一才会产生新的位数,也就是对答案做出了贡献
而每进一位,1的个数就会多一个
所以每一个数字出现了几次,每一个数字都会站一位,所以操作后的长度就是每个数字出现的个数
然后对询问的答案,我们每一位拆分之后把该位对应的数字变成几位的答案累加就行了
// Problem: C. Add One
// Contest: Codeforces - Divide by Zero 2021 and Codeforces Round #714 (Div. 2)
// URL: https://codeforces.com/contest/1513/problem/C
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define ll long long
#define re return
using namespace std;
const int MOD = 1e9 + 7;
typedef pair<int, int> PII;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int n;
int m;
int ans[200000 + 10][10]; // 用来记录每个数字经过m次操作后长度为几
void init(){
for(int i = 0; i <= 9; i++){
ans[0][i] = 1; // 操作0次答案自然就是1
ll cnt[10] = {0}; // 每个数在每次操作后出现了多少次
ll t[10] = {0}; // 这个数在在m次操作中的某一个操作中,每个数出现了多少次
cnt[i]++; // 这一个数字出现过一次
for(int j = 1; j <= 200000; j++){
for(int k = 0; k <= 9; k++){
t[(k + 1) % 10] = cnt[k]; //每一位数字加一后变成新的数字,但他不会对答案做出贡献
}
t[1] += cnt[9]; // 9在操作后会新增出来一个1,1的个数就会变多了
ll summ = 0;
for(int k = 0; k <= 9; k++){
summ += t[k]; // 提议分析
summ %= MOD;
cnt[k] = t[k] % MOD; // 下一次操作,每个数分别有几个
}
ans[j][i] = summ;
}
}
}
void work(){
char s[20];
scanf("%s%d", s, &m); // 打表卡cin
ll a = 0;
int l = strlen(s);
ll a = 0;
for(int i = 0; i < l; i++){
a = (a + ans[m][int(s[i] - '0')]) % MOD; // 答案构成
}
printf("%lld\n", a % MOD);
}
int main(){
init();
int T;
cin >> T;
while(T--){
work();
}
return 0;
}