[HDU 4507] 吉哥系列故事――恨7不成妻

求所有满足要求的数的平方和

不只是统计个数,而是与每个数得具体取值有关

维护三个值

dp[dep][sum][num].num表示长度为dep的前面的数模7的余数为sum,前面几位数字之和模7为num的满足要求的数的个数

dp[dep][sum][num].sum表示长度为dep的前面的数模7的余数为sum,前面几位数字之和模7为num的满足要求的数的和

dp[dep][sum][num].sq表示长度为dep的前面的数模7的余数为sum,前面几位数字之和模7为num的满足要求的数的平方和

设当前位位i,则有如下转移

  tmp=dfs(dep-1,(sum*10+i)%7,(num+i)%7,flag&&(i==lim))

  ans.sq+=tmp.num*(i*mi_10[dep-1])^2+2*(i*mi_10[dep-1])*tmp.sum+tmp.sq

  ans.sum+=tmp.num*(i*mi_10[dep-1])+tmp.sum

  ans.num+=tmp.num

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define mod 1000000007
 5 struct node{ ll sq,sum,num; }dp[20][20][10];
 6 int dig[20];
 7 ll mi_10[20];
 8 ll sq(ll x){ return x*x%mod; }
 9 node dfs(int dep,int sum,int num,int flag){
10     if(!dep)return (node){0,0,sum&&num};
11     if(!flag&&dp[dep][sum][num].num!=-1)return dp[dep][sum][num];    
12     int lim=flag?dig[dep]:9;
13     node ans={0,0,0};
14     for(int i=0;i<=lim;i++){
15         if(i==7)continue;
16         node tmp=dfs(dep-1,(sum*10+i)%7,(num+i)%7,flag&&(i==lim));
17         ll cur=i*mi_10[dep-1]%mod;
18         ans.sq=(ans.sq+((tmp.num*sq(cur)%mod+2*cur%mod*tmp.sum%mod)%mod+tmp.sq)%mod)%mod;
19         ans.sum=(ans.sum+(tmp.num*cur%mod+tmp.sum)%mod)%mod;
20         ans.num=(ans.num+tmp.num)%mod;
21     }
22     if(!flag)dp[dep][sum][num]=ans;
23     return ans;
24 }
25 ll solve(ll x){
26     int dd=0;
27     while(x)dig[++dd]=x%10,x/=10;
28     return dfs(dd,0,0,1).sq;
29 }
30 int main(){
31     int T;
32     scanf("%d",&T);
33     memset(dp,-1,sizeof(dp));
34     mi_10[0]=1LL;
35     for(int i=1;i<20;i++)
36         mi_10[i]=mi_10[i-1]*10%mod;
37     while(T--){
38         ll A,B;
39         scanf("%lld%lld",&A,&B);
40         printf("%lld\n",((solve(B)-solve(A-1))%mod+mod)%mod);
41     }
42     return 0;
43 }
View Code

 

posted @ 2016-05-19 13:40  Ngshily  阅读(449)  评论(0编辑  收藏  举报