hdu4507 数位dp~last(求一个区间内所有与7无关数的平方和)

因为这道题目开始学的数位dp,在bestcode那道数位dp(http://www.cnblogs.com/xiao-xin/articles/4168112.html)解决之后,这道题目也终于解决啦!

求一个区间内满足:1.每位都没有7 2.该数每位和不是7倍数 3.该数不是7倍数,这样的数的平方和。

很显然,我们dfs套的是  pos,sum,x,flag,limit 分别表示位,该数%7,该数各位和%7,前面有没有出现7,有没有到达上限 

但是对于我们要求的所有符合要求的平方和我们该如何返回?

返回三个参数 符合要求个数,符合要求的数的和,符合要求的数的平方和;我们用一个结构体保存,为什么是三个参数:

(thingking所求平方和递推关系)

另外,本题不用求反面,求反面反而要用逆元,直接求就好啦!

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #define LL long long
 5 #define MOD 1000000007
 6 using namespace std;
 7 struct dian{
 8   LL num,sum1,sum2;
 9 }dp[25][10][10][2];
10 LL vis[25][10][10][2];
11 LL f[25],num[20];
12 dian dfs(LL pos,LL sum,LL x,LL flag,LL limit)
13 {
14   LL i,tmp,temp;
15   dian n1,n2;
16   if (pos==0)
17   {
18     n1.sum1=n1.sum2=0;
19     n1.num=1;
20     if (sum==0||x==0||flag) n1.num=0;
21     return n1;
22   }
23   if (!limit&&vis[pos][sum][x][flag]!=-1)
24     return dp[pos][sum][x][flag];
25   tmp=limit?num[pos]:9;
26   n1.num=n1.sum1=n1.sum2=0;
27   for (i=0;i<=tmp;i++)
28   {
29     n2=dfs(pos-1,(sum*10+i)%7,(x+i)%7,flag||i==7,limit&&i==tmp);
30     n1.num=(n1.num+n2.num)%MOD;
31     n1.sum1=(n1.sum1+n2.sum1+((f[pos-1]*i)%MOD*n2.num)%MOD)%MOD;
32     temp=i*f[pos-1]%MOD;
33     n1.sum2=(n1.sum2+(temp*temp%MOD)*n2.num%MOD+
34             temp*n2.sum1%MOD*2+n2.sum2)%MOD;
35   }
36   if (!limit)
37   {
38     vis[pos][sum][x][flag]=1;
39     dp[pos][sum][x][flag]=n1;
40   }
41   return n1;
42 }
43 int main()
44 {
45   int T;
46   dian n1,n2;
47   LL i,l,r,cnt,temp1,temp;
48   f[0]=1;
49   for  (i=1;i<=19;i++)
50     f[i]=(f[i-1]*10)%MOD;
51   scanf("%d",&T);
52   while (T--)
53   {
54     scanf("%I64d%I64d",&l,&r);
55     n1.sum2=n2.sum2=0;
56     memset(vis,-1,sizeof(vis));
57     cnt=0;
58     while (r>0)
59     {
60       num[++cnt]=r%10;
61       r/=10;
62     }
63     if (cnt>0) n1=dfs(cnt,0,0,0,1);
64     cnt=0; l--;
65     while (l>0)
66     {
67       num[++cnt]=l%10;
68       l/=10;
69     }
70     if (cnt>0) n2=dfs(cnt,0,0,0,1);
71     temp=((n1.sum2-n2.sum2)%MOD+MOD)%MOD;
72     printf("%I64d\n",temp);
73   }
74   return 0;
75 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4507

posted on 2014-12-20 09:31  xiao_xin  阅读(241)  评论(0编辑  收藏  举报

导航