单身!
依然单身!
吉哥依然单身!
DS级码农吉哥依然单身!
所以,他生平最恨情人节,不管是214还是77,他都讨厌!
吉哥观察了214和77这两个数,发现:
2+1+4=7
7+7=7*2
77=7*11
最终,他发现原来这一切归根到底都是因为和7有关!所以,他现在甚至讨厌一切和7有关的数!
什么样的数和7有关呢?
如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关——
1、整数中某一位是7;
2、整数的每一位加起来的和是7的整数倍;
3、这个整数是7的整数倍;
现在问题来了:吉哥想知道在一定区间内和7无关的数字的平方和。
依然单身!
吉哥依然单身!
DS级码农吉哥依然单身!
所以,他生平最恨情人节,不管是214还是77,他都讨厌!
吉哥观察了214和77这两个数,发现:
2+1+4=7
7+7=7*2
77=7*11
最终,他发现原来这一切归根到底都是因为和7有关!所以,他现在甚至讨厌一切和7有关的数!
什么样的数和7有关呢?
如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关——
1、整数中某一位是7;
2、整数的每一位加起来的和是7的整数倍;
3、这个整数是7的整数倍;
现在问题来了:吉哥想知道在一定区间内和7无关的数字的平方和。
Input输入数据的第一行是case数T(1 <= T <= 50),然后接下来的T行表示T个case;每个case在一行内包含两个正整数L, R(1 <= L <= R <= 10^18)。
Output请计算[L,R]中和7无关的数字的平方和,并将结果对10^9 + 7 求模后输出。Sample Input
3 1 9 10 11 17 17
Sample Output
236 221 0
思路:还是数位DP,套用模板,求的是平方和,记录其后数位满足条件的个数即可,比如233, 234, 235满足,则平方和为(200+33)^2+(200+34)^2+(200+35)^2 = 3*200^2 + 2*200*(33+34+35)+33^2+34^2+35^2,记录下每次的和与平方和维护即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
typedef long long LL; typedef pair<LL, LL> PLL; const int MOD = 1e9+7; struct Node { LL num, sum, ssum; } dp[20][10][10]; LL a[20], p[20]; Node dfs(int pos, int pre, int presum, bool limit) { if(pos == -1) { Node ret; ret.num = (pre != 0 && presum != 0); ret.sum = ret.ssum = 0; return ret; } if(!limit && dp[pos][pre][presum].num != -1) return dp[pos][pre][presum]; int up = limit?a[pos]:9; Node ans; ans.num = ans.sum = ans.ssum = 0; for(int i = 0; i <= up; ++i) { if(i == 7) continue; Node nex = dfs(pos-1, (pre+i)%7, (presum*10+i)%7, limit&&i==a[pos]); if(nex.num == 0) continue; ans.num = ((ans.num + nex.num) % MOD + MOD) % MOD; ans.sum = ((ans.sum + nex.sum + (p[pos]*i)%MOD*nex.num) % MOD + MOD) % MOD; ans.ssum = ((ans.ssum + nex.ssum + ((2*p[pos]*i) % MOD)*nex.sum) % MOD + MOD) % MOD; ans.ssum = ((ans.ssum + (p[pos]*nex.num)%MOD * p[pos] % MOD *i*i) % MOD + MOD) % MOD; } if(!limit) dp[pos][pre][presum] = ans; return ans; } LL solve(LL n, LL m) { int pos = 0; while(n) { a[pos++] = n % 10; n /= 10; } LL t1 = dfs(pos-1, 0, 0, true).ssum; pos = 0; while(m) { a[pos++] = m % 10; m /= 10; } t1 = dfs(pos-1, 0, 0, true).ssum - t1; return (t1%MOD+MOD)%MOD; } void run_case() { LL n, m; cin >> n >> m; cout << solve(n-1, m) << " "; } int main() { ios::sync_with_stdio(false), cin.tie(0); int t; cin >> t; for(int i = 0; i < 20; ++i) for(int j = 0; j < 10; ++j) for(int k = 0; k < 10; ++k) dp[i][j][k].num = -1; p[0] = 1; for(int i = 1; i < 20; ++i) p[i] = (p[i-1]*10)%MOD; while(t--) run_case(); return 0; }