hdu 4507 吉哥系列故事——恨7不成妻

http://acm.hdu.edu.cn/showproblem.php?pid=4507

用dp结构体里面存有符合要求的个数cnt,各位数和的sum1,符合要求的数的平方和sum2三个值。在维护sum2时需要用到sum1和cnt两个值。

数位dp

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define LL __int64
 5 using namespace std;
 6 const LL mod=1000000007;
 7 
 8 struct node
 9 {
10     LL cnt;
11     LL sum1;
12     LL sum2;
13 } dp[30][30][30];
14 int num[30];
15 LL c[30];
16 
17 node dfs(int pos,int sum1,int sum2,bool flag)
18 {
19     if(pos==-1)
20     {
21         node st;
22         st.cnt=(sum1!=0&&sum2!=0);
23         st.sum1=0;
24         st.sum2=0;
25         return st;
26     }
27     if(!flag&&dp[pos][sum1][sum2].cnt!=-1) return dp[pos][sum1][sum2];
28     node ans;
29     ans.cnt=0;
30     ans.sum1=0;
31     ans.sum2=0;
32     node st1;
33     int xx=flag?num[pos]:9;
34     for(int i=0; i<=xx; i++)
35     {
36         if(i==7) continue;
37         st1=dfs(pos-1,(sum1+i)%7,(sum2*10+i)%7,flag&&(i==xx));
38         ans.cnt+=st1.cnt;
39         ans.cnt%=mod;
40         ans.sum1+=(st1.sum1+((c[pos]*i%mod)*st1.cnt)%mod)%mod;
41         ans.sum1%=mod;
42         ans.sum2+=(((st1.cnt*c[pos])%mod*c[pos]%mod*i*i)%mod);
43         ans.sum2%=mod;
44         ans.sum2+=(st1.sum2+((2*c[pos]*i)%mod)*st1.sum1)%mod;
45         ans.sum2%=mod;
46     }
47     if(!flag) dp[pos][sum1][sum2]=ans;
48     return ans;
49 }
50 
51 LL get(LL n)
52 {
53     int cnt=0;
54     while(n)
55     {
56         num[cnt++]=n%10;
57         n=n/10;
58     }
59     node a=dfs(cnt-1,0,0,true);
60     return a.sum2;
61 }
62 
63 void inti()
64 {
65     c[0]=1;
66     for(int i=1; i<20; i++)
67     {
68         c[i]=(c[i-1]*10)%mod;
69     }
70     for(int i=0; i<20; i++)
71     {
72         for(int j=0; j<20; j++)
73         {
74             for(int k=0; k<20; k++)
75             {
76               dp[i][j][k].cnt=-1;
77             }
78         }
79     }
80 }
81 int main()
82 {
83     int t;
84     scanf("%d",&t);
85     inti();
86     while(t--)
87     {
88         LL n,m;
89         scanf("%I64d%I64d",&n,&m);
90         printf("%I64d\n",((get(m)-get(n-1))%mod+mod)%mod);
91     }
92     return 0;
93 }
View Code

 

posted @ 2014-10-22 23:23  null1019  阅读(199)  评论(0编辑  收藏  举报