HDU 4507 吉哥系列故事——恨7不成妻 (比较繁琐的数位DP)
2013-12-08 14:32
465 查看
题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=4507
题意 :找出[l, r]之间所有不满足以下任意一条的数的平方之和 :
1、整数中某一位是7;
2、整数的每一位加起来的和是7的整数倍;
3、这个整数是7的整数倍;
思路 : 数位DP, 繁琐的是处理平方和,可以这样考虑当你算到len位的时候获得的数字是x,然后下一位放进去的数字是i,那么其实所获得的新的值应该是x + i * 10 ^ (len-1), 然后要计算它的平方, 那么展开后就是 x * x + f * f + 2 * f * x ;(f = i * 10 ^ (len - 1)),这样的话需要统计在前继状态中获得的所有满足条件的数的个数cnt, 所有满足条件的数的和s1, 所有满足条件的数的平方和s2.然后用GYZ的数位DP写法秒了, 注意下别溢出即可。
PS : 一开始打算是把当前算到的位置所获得数字平方和传进去, 但是空间更本就是开不下的。看了爱神(cxlove)的blog才发现原来可以倒的把数据返回来, 这样就不需要担心爆内存了。
题意 :找出[l, r]之间所有不满足以下任意一条的数的平方之和 :
1、整数中某一位是7;
2、整数的每一位加起来的和是7的整数倍;
3、这个整数是7的整数倍;
思路 : 数位DP, 繁琐的是处理平方和,可以这样考虑当你算到len位的时候获得的数字是x,然后下一位放进去的数字是i,那么其实所获得的新的值应该是x + i * 10 ^ (len-1), 然后要计算它的平方, 那么展开后就是 x * x + f * f + 2 * f * x ;(f = i * 10 ^ (len - 1)),这样的话需要统计在前继状态中获得的所有满足条件的数的个数cnt, 所有满足条件的数的和s1, 所有满足条件的数的平方和s2.然后用GYZ的数位DP写法秒了, 注意下别溢出即可。
PS : 一开始打算是把当前算到的位置所获得数字平方和传进去, 但是空间更本就是开不下的。看了爱神(cxlove)的blog才发现原来可以倒的把数据返回来, 这样就不需要担心爆内存了。
#include #include #include using namespace std; typedef __int64 lld; const int mod = 1e9 + 7; int bit[20]; lld cnt[20][2][7][7], s1[20][2][7][7], s2[20][2][7][7]; lld Fac[20]; struct Bo{ lld cnt, s1, s2; Bo(){} Bo(lld a, lld b, lld c) : cnt(a), s1(b), s2(c){} }; Bo dfs(int len, int a, int b, int c, int fp){ if (!fp && cnt[len][a][b][c] != (lld)-1){ return Bo(cnt[len][a][b][c], s1[len][a][b][c], s2[len][a][b][c]); } if (!len){ if (!a && b && c){ cnt[len][a][b][c] = 1; }else { cnt[len][a][b][c] = 0; } s1[len][a][b][c] = s2[len][a][b][c] = 0; return Bo(cnt[len][a][b][c], s1[len][a][b][c], s2[len][a][b][c]); } int Max = (fp ? bit[len] : 9); lld vc = 0, vs1 = 0, vs2 = 0; for (int i = 0; i <= Max; i++){ int nl = len - 1 , na = (a || i == 7), nb = (b + i) % 7, nc = (c * 10 + i) % 7; Bo tmp = dfs(nl, na, nb, nc, i == Max && fp); lld f = Fac[nl] * i % mod; vc = (vc + tmp.cnt) % mod; vs1 = (vs1 + tmp.s1 + tmp.cnt * f) % mod; vs2 = (vs2 + tmp.s2 + (f * f) % mod * tmp.cnt + 2 * f * tmp.s1) % mod; } if (!fp){ cnt[len][a][b][c] = vc; s1[len][a][b][c] = vs1; s2[len][a][b][c] = vs2; } return Bo(vc, vs1, vs2); } lld solve(lld x){ lld tmp = x; int len = 0; while (tmp){ bit[++len] = tmp % 10; tmp /= 10; } Bo res = dfs(len, 0, 0, 0, 1); return res.s2 % mod; } void init(){ Fac[0] = 1; for (int i = 1; i <= 18; i++){ Fac[i] = Fac[i-1] * 10 % mod; } memset(cnt, -1, sizeof(cnt)); } int main(){ int T; scanf("%d", &T); init(); for (int cas = 1; cas <= T; cas++){ lld l, r; scanf("%I64d%I64d", &l, &r); printf("%I64d\n", (solve(r) - solve(l - 1) + mod) % mod); } return 0; }
相关文章推荐
- HDU 4507 吉哥系列故事——恨7不成妻(数位DP)
- HDU 4507 吉哥系列故事――恨7不成妻 数位DP
- [HDU 4507] 吉哥系列故事——恨7不成妻 数位dp
- 数位dp_HDU_4507_吉哥系列故事——恨7不成妻
- HDU 4507 吉哥系列故事——恨7不成妻[数位dp]
- HDU 4507 吉哥系列故事——恨7不成妻(数位DP)
- HDU 4507 吉哥系列故事——恨7不成妻(数位DP)
- hdu 4507 - 吉哥系列故事——恨7不成妻(数位dp)
- hdu_4507_吉哥系列故事——恨7不成妻(鬼畜数位DP)
- HDU-4507 吉哥系列故事――恨7不成妻 (数位dp)
- HDU 4507 吉哥系列故事——恨7不成妻(数位DP)
- hdu_4507_吉哥系列故事——恨7不成妻(鬼畜数位DP)
- HDU-4507 吉哥系列故事——恨7不成妻 数位DP
- HDU 4507 吉哥系列故事——恨7不成妻(数位DP)
- HDU 4507 吉哥系列故事——恨7不成妻 数位DP
- HDU 4507 吉哥系列故事——恨7不成妻 数位dp
- hdu 4507 吉哥系列故事――恨7不成妻 数位dp
- HDU 4507 吉哥系列故事 恨7不成妻 (数位dp)
- [数位dp] hdu 4507 吉哥系列故事——恨7不成妻
- HDU 4507 吉哥系列故事——恨7不成妻 (数位DP)