吉哥系列故事——恨7不成妻
Time Limit: 1000/500 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 2532 Accepted Submission(s): 747
Problem Description
单身!
依然单身!
吉哥依然单身!
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。
设后i-1位合法的数字有N个,num1, num2, num3, num4...numN考虑第i位的x,则num = 10^(i-1) * x。
和为num * N +(num1 + ... + numN)。
平方和为(num + num1)^2 + (num + num2) ^ 2 + (num + num3) ^ 2 + ... + (num + numN) ^ 2。
化简后 = N * num^2 + 2 * num * (num1+...+numN) + (num1^2 + ... + numN^2)。
用dp维护个数cnt,和sum1, 平方和sum2即可。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <string>
#define INF 1000000
#define eps 1e-8
#define MAXN (200000+10)
#define MAXM (100000+10)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while((a)--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
#pragma comment(linker, "/STACK:102400000,102400000")
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pii;
struct Node{
LL cnt, sum1, sum2;
};
Node dp[30][7][7];
int bit[30];
LL P[30];
void Init()
{
CLR(dp, -1);
P[0] = 1LL;
for(int i = 1; i < 30; i++)
P[i] = P[i-1] * 10 % MOD;
}
void add(LL &x, LL y)
{
x += y;
x %= MOD;
}
LL Fac(LL x){
return x * x % MOD;
}
Node DFS(int pos, int presum, int preyu, bool yes)
{
if(pos == -1)
{
Node temp; temp.cnt = (presum && preyu);
temp.sum1 = temp.sum2 = 0LL;
return temp;
}
if(!yes && dp[pos][presum][preyu].cnt != -1) return dp[pos][presum][preyu];
Node ans, temp; ans.cnt = ans.sum1 = ans.sum2 = 0LL;
int End = yes ? bit[pos] : 9;
for(int i = 0; i <= End; i++)
{
if(i == 7) continue;
temp = DFS(pos-1, (presum+i)%7, (preyu*10+i)%7, yes&&i==End);
add(ans.cnt, temp.cnt);
add(ans.sum1, (temp.sum1 + temp.cnt * P[pos] % MOD * i % MOD) % MOD);
add(ans.sum2, ((temp.cnt * Fac(P[pos]) % MOD * Fac(i) % MOD + temp.sum2) % MOD + temp.sum1 * 2 % MOD * P[pos] % MOD * i % MOD) % MOD);
}
if(!yes) dp[pos][presum][preyu] = ans;
return ans;
}
LL Count(LL n)
{
int len = 0;
while(n)
{
bit[len++] = n % 10;
n /= 10;
}
return DFS(len-1, 0, 0, 1).sum2;
}
int main()
{
Init();
int t; Ri(t);
W(t)
{
LL n, m; Rl(n); Rl(m);
Pl(((Count(m) - Count(n-1)) % MOD + MOD) % MOD);
}
return 0;
}