题目概述
求
[L,R]
中同时满足[1.不存在
7
。2.不是
解题报告
恩……又是数位DP水……水个头啊,平方和是什么鬼???
这道题要用平方和公式
然后将一个数 x 看做每位相加,比如:
这样就可以方便的转移了。详细一点?不如膜拜ChesterKing!
发现记忆化真的好写……感觉又重学了一遍数位DP……
示例程序
#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn=19,MOD=1e9+7;
int te,a[maxn+5];LL L,R,p[maxn+5];
inline void AMOD(LL &x,LL tem) {if ((x+=tem)>=MOD) x-=MOD;}
#define Mod(x) ((x)%MOD)
struct data
{
LL num,sum,sqr;data(LL A=-1,LL B=-1,LL C=-1) {num=A;sum=B;sqr=C;}
void Add(const data &c,int i,int x)
{
AMOD(num,c.num);AMOD(sum,Mod(c.sum+Mod(p[x]*c.num)*i));
AMOD(sqr,Mod(c.sqr+Mod(p[x]*c.sum)*i*2+Mod(Mod(Mod(p[x]*i)*Mod(p[x]*i))*c.num)));
}
};
data f[maxn+5][7][7];
void Make() {p[0]=1;for (int i=1;i<=maxn;i++) p[i]=Mod(p[i-1]*10);}
data Dfs(int i,int A,int M,bool fl)
{
if (!i) return data(A&&M,0,0);if (!fl&&~f[i][A][M].sqr) return f[i][A][M];
int MAX=9;if (fl) MAX=a[i];data ans=data(0,0,0);
for (int j=0;j<=MAX;j++) if (j!=7)
ans.Add(Dfs(i-1,(A+j)%7,((M<<3)+(M<<1)+j)%7,fl&&j==MAX),j,i-1);
if (!fl) f[i][A][M]=ans;return ans;
}
inline int Solve(LL n)
{
a[0]=0;do a[++a[0]]=n%10,n/=10; while (n);
return Dfs(a[0],0,0,true).sqr;
}
int main()
{
freopen("program.in","r",stdin);
freopen("program.out","w",stdout);
for (Make(),scanf("%d",&te);te;te--) scanf("%lld%lld",&L,&R),printf("%d\n",Mod(Solve(R)+MOD-Solve(L-1)));
return 0;
}