数位dp 数据取余注意事项
AcWing 1086. 恨7不成妻
数位dp例题
注意一个数不能分别对两个不同的数取余,只能将其保存下来
例如下面代码中的prev_b

#include<bits/stdc++.h> using namespace std; typedef long long LL; LL MOD = 1000000007; struct AllSum { LL s0, s1, s2; }; AllSum dp[20][10][7][7];//len head all_digit%7 num%7 LL power10_7[20]; LL power10_MOD[20]; LL power10_no[20]; LL Mod(LL a, LL b) { return (a%b + b) % b; } LL Count(LL num) { if (num == 0) return 0; LL o = num; string nums = to_string(num); reverse(nums.begin(), nums.end()); LL res = 0; LL prev_a = 0, prev_b = 0; for (int i = nums.size() - 1; i >= 0; i--) { LL num = nums[i] - '0'; for (int j = 0; j < num; j++) { if (j == 7) continue; LL s0=0, s1=0, s2=0; for (int b = 0; b < 7; b++) { for (int a = 0; a < 7; a++) { LL cur_a = prev_a + a; LL cur_b = prev_b + b; cur_a %= 7; cur_b %= 7; if (cur_a != 0 && cur_b != 0) { s0 += dp[i + 1][j][a][b].s0; s1+= dp[i + 1][j][a][b].s1; s2+= dp[i + 1][j][a][b].s2; s0 %= MOD; s1 %= MOD; s2 %= MOD; } } } res += (prev_b % MOD)*(prev_b%MOD) % MOD*s0%MOD + 2 * prev_b%MOD*s1%MOD + s2; res %= MOD; } if (num == 7) break; prev_a = prev_a + num; prev_b = prev_b + num*power10_no[i]; //prev_a %= MOD; //prev_b %= MOD; if (prev_a%7 != 0 && prev_b%7 != 0 && num!=7&&i == 0) { res += o%MOD * (o%MOD)%MOD; } } return res%MOD; } void YD(LL T) { LL a=T-1, b=T; cin >> a >> b; cout <<Mod(Count(b) - Count(a - 1), MOD) << endl; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int T = 1; cin >> T; for (int i = 0; i < 10; i++) { if(i!=7) dp[1][i][i % 7][i % 7] = { 1,i,i*i }; } LL power10 = 10; for (int i = 2; i < 20; i++,power10*=10) { for (int j = 0; j < 10; j++) { if (j == 7) continue; for (int a = 0; a < 7; a++) { for (int b = 0; b < 7; b++) { for (int k = 0; k < 10; k++) { if (k == 7) continue; auto &cur = dp[i][j][a][b]; auto &prev = dp[i - 1][k][Mod(a-j,7)][Mod(b-j*Mod(power10,7),7)]; cur.s0 = (cur.s0 + prev.s0) % MOD; cur.s1 = (cur.s1+(prev.s0*j%MOD*(power10%MOD)%MOD+prev.s1)%MOD)%MOD; cur.s2 = (cur.s2+prev.s0*j%MOD*j%MOD*(power10%MOD)%MOD*(power10%MOD)%MOD + 2 * j*(power10%MOD)%MOD*prev.s1%MOD + prev.s2)%MOD; } } } } } power10_no[0]=power10_7[0] = power10_MOD[0] = 1; for (int i = 1; i < 20; i++) { power10_7[i] = power10_7[i - 1] * 10 % 7; power10_MOD[i] = power10_MOD[i - 1] * 10LL % MOD; power10_no[i] = power10_no[i - 1] * 10LL ; } while (T--) { YD(T); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人