中文题
做法:奇葩,要求区间中数字的平方和。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; }