吉哥系列故事——恨7不成妻
Time Limit: 1000/500 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1117 Accepted Submission(s): 336
依然單身!
吉哥依然單身!
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無關的數字的平方和。
/*
ID: xinming2
PROG: stall4
LANG: C++
*/
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <map>
#include <string>
#include <stack>
#include <cctype>
#include <vector>
#include <queue>
#include <set>
#include <utility>
#include <cassert>
using namespace std;
///#define Online_Judge
#define outstars cout << "***********************" << endl;
#define clr(a,b) memset(a,b,sizeof(a))
#define lson l , mid , rt << 1
#define rson mid + 1 , r , rt << 1 | 1
#define mk make_pair
#define FOR(i , x , n) for(int i = (x) ; i < (n) ; i++)
#define FORR(i , x , n) for(int i = (x) ; i <= (n) ; i++)
#define REP(i , x , n) for(int i = (x) ; i > (n) ; i--)
#define REPP(i ,x , n) for(int i = (x) ; i >= (n) ; i--)
const int MAXN = 100000 + 50;
const int sigma_size = 26;
const long long LLMAX = 0x7fffffffffffffffLL;
const long long LLMIN = 0x8000000000000000LL;
const int INF = 0x7fffffff;
const int IMIN = 0x80000000;
#define eps 1e-8
const int mod = (int)1e9 + 7;
typedef long long LL;
const LL MOD = 1000000007LL;
const double PI = acos(-1.0);
typedef pair<int , int> pi;
#define Bug(s) cout << "s = " << s << endl;
///#pragma comment(linker, "/STACK:102400000,102400000")
struct Num
{
LL cnt;///與7無關的個數
LL sum;///與7無關的個數和
LL sqsum;///平方和
}dp[20][20][20];///dp[i][j][k]表示處理的位數,數字和%7,數字%7
int digit[20];
LL p[20];///p[i] = 10^ i;
Num dfs(int pos , int pre1 , int pre2, bool fp)
{
if(pos == -1)
{
Num tmp;
tmp.cnt = (pre1 != 0) && (pre2 != 0);
tmp.sum = tmp.sqsum = 0;
return tmp;
}
if(!fp && dp[pos][pre1][pre2].cnt != -1)return dp[pos][pre1][pre2];
int maxi = fp ? digit[pos] : 9;
Num ans , tmp;
ans.cnt = ans.sqsum = ans.sum = 0;
for(int i = 0 ; i <= maxi ; i++)
{
if(i == 7)continue;
tmp = dfs(pos - 1 , (pre1 + i) % 7 , (pre2 * 10 + i)% 7 , fp && i == maxi);
ans.cnt += tmp.cnt;
ans.cnt %= MOD;
ans.sum += (tmp.sum + ((p[pos] * i) % MOD) * tmp.cnt % MOD) % MOD;
ans.sum %= MOD;
ans.sqsum += (tmp.sqsum + ((2 * p[pos] * i) % MOD) *tmp.sum) % MOD;///next^2 + 2*pre*10^pos*next
ans.sqsum %= MOD;
ans.sqsum += (tmp.cnt * p[pos]) % MOD * p[pos] % MOD * i * i % MOD;///(pre*10^pos)^2
ans.sqsum %= MOD;
}
if(!fp)dp[pos][pre1][pre2] = ans;
return ans;
}
LL f(LL n)
{
int len = 0;
while(n)
{
digit[len++] = n % 10;
n /= 10;
}
return dfs(len - 1, 0 , 0 , 1).sqsum;
}
int main()
{
int T;
LL a , b;
p[0] = 1;
for(int i = 1 ; i < 20 ; i++)
{
p[i] = (p[i - 1] * 10) % MOD;
}
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].cnt = -1;
}
}
}
scanf("%d" , &T);
while(T--)
{
scanf("%I64d%I64d" , &a , &b);
LL ans = f(b) - f(a - 1);
printf("%I64d\n" , (ans % MOD + MOD ) % MOD);
}
return 0;
}