中文题
做法:奇葩,要求区间中数字的平方和。sigma(a1,a2... an) = n*sigma(first)*sigma(first) + 2*sigma(first)*sigma(he) + sigma(squre);
a1,..a2...an代表区间中的每个数, first 代表他们共用的首位*10^(i - 1),i是这个数的位数,squre 代表平方和, he 代表其他位数组成数字的和。
#include <cstdio>
#include <cstring>
typedef __int64 LL;
const int mod = 1000000000 + 7;
const int LMT = 7;
const int LEN = 20;
//一开始的取膜方法写错了,重复不同数的取膜最后答案会错误
//为了保险,能取模就取模
LL _squre[7][7][LEN], _sum[7][7][LEN],ten[LEN], have[7][7][LEN];
int num[LEN];
void init(void)
{
memset(_squre, -1, sizeof(_squre));
memset(_sum, -1, sizeof(_sum));
memset(have, -1, sizeof(have));
}
struct __ret
{
LL sq, sm, hv;
__ret(LL a, LL b, LL c): sq(a), sm(b), hv(c) {}
__ret():sq(0), sm(0), hv(0){}
};
__ret dfs(const int &now, const int &rest, const int &sum, const bool &tag)
{
if(rest == 0)
{
if (now && sum) return __ret(0, 0, 1);
else return __ret(-1, -1, 0);
}
if (!tag && _squre[now][sum][rest] != -1)
return __ret(_squre[now][sum][rest], _sum[now][sum][rest], have[now][sum][rest]);
int i,end = (tag ? num[rest] : 9);
__ret tem;
LL sqr = 0, sm = 0, hv = 0, prep;
for(i = 0; i <= end; ++i)
if(i != 7)
{
prep = i * ten[rest - 1] % mod;
tem = dfs((now*10 + i)% 7, rest - 1, (sum + i) % 7, tag && (i == end));
if(tem.sq != -1)
{
sqr += (prep * prep % mod * tem.hv % mod + 2 * tem.sm * prep %mod + tem.sq) % mod;
sqr %= mod;
sm += (tem.hv%mod*prep % mod + tem.sm) % mod;
sm %= mod;
hv += tem.hv;
hv %= mod;
}
}
if(!tag)//这里又错了return了数组值,哭...
{
_squre[now][sum][rest] = sqr;
_sum[now][sum][rest] = sm;
have[now][sum][rest] = hv;
}
return __ret(sqr, sm, hv);
}
int get_num(LL x)
{
int res = 0;
do
num[++res] = int(x % 10);
while(x /= 10);
return res;
}
int main(void)
{
init();
int T,lena,lenb;
LL a,b,resa,resb, ans;
init();
ten[0] = 1;
for(int i = 1; i <= 18; ++i)
ten[i] = (ten[i - 1] * 10) % mod;
scanf("%d", &T);
while(T--)
{
scanf("%I64d%I64d",&a, &b);
if(a > b)
{
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
a--;
lena = get_num(a);
resa = dfs(0, lena, 0, 1).sq;
lenb = get_num(b);
resb = dfs(0, lenb, 0, 1).sq;
ans = resb - resa;
if(ans < 0) ans = ans + mod;
printf("%I64d\n", ans);
}
return 0;
}