3 1 9 10 11 17 17
236 221 0
[L,R]内所有满足条件的数的平方和是多少。
这题有点。。重点在于怎么求平方和。
维护的dp值不止一个,要维护3个,dp[cur][sum1][sum2]里的a,a2,n。表示当前处理到cur位置,前面的数mod7=sum1,前面的数位和mod7=sum2,这个状态下后面所有满足的取值、后面这些位的和为a,平方和为a2,共有n个数。可以根据a,a2,n推出当前的a',a2',n',相当于已知a1+..+an,a1^2+..+an^2,求(a1+b)^2+(a2+b)^2..+(an+b)^2。若当前这一位取i,a'+=i*10^cur*n+a,a2'+=(10^cur)^2*i^2*n+2*10^cur*i*a+a2,n'+=n。
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> using namespace std; typedef long long LL; const int MAXN=70; const LL MOD=1000000007; int T; LL L,R; int bit[MAXN]; bool vis[MAXN][10][10]; LL power[20]; struct DP{ LL a,a2,n; }dp[MAXN][10][10]; DP dfs(int cur,int sum1,int sum2,int e){ if(cur<0){ if(sum1%7&&sum2%7) return (DP){0,0,1}; return (DP){0,0,0}; } if(!e&&vis[cur][sum1][sum2]) return dp[cur][sum1][sum2]; int end=e?bit[cur]:9; LL b=0,b2=0,n=0; DP tmp; for(int i=0;i<=end;i++) if(i!=7){ tmp=dfs(cur-1,(sum1*10+i)%7,(sum2+i)%7,e&&i==end); if(tmp.n>0){ b=(b+(i*power[cur])%MOD*tmp.n%MOD+tmp.a)%MOD; b2=(b2+((power[cur]*power[cur]%MOD*i*i)%MOD*tmp.n%MOD+(2*power[cur]*i%MOD*tmp.a)%MOD+tmp.a2)%MOD)%MOD; n=(n+tmp.n)%MOD; } } if(!e){ vis[cur][sum1][sum2]=1; dp[cur][sum1][sum2]=(DP){b,b2,n}; } return (DP){b,b2,n}; } LL solve(LL n){ int len=0; while(n){ bit[len++]=n%10; n/=10; } return dfs(len-1,0,0,1).a2; } int main(){ freopen("in.txt","r",stdin); scanf("%d",&T); power[0]=1; for(int i=1;i<=18;i++) power[i]=(power[i-1]*10)%MOD; memset(vis,0,sizeof(vis)); while(T--){ scanf("%I64d%I64d",&L,&R); printf("%I64d\n",(solve(R)-solve(L-1)+MOD)%MOD); } return 0; }