您的位置:首页 > 其它

hdu4507吉哥系列故事——恨7不成妻 数位dp

2015-05-04 16:02 295 查看
//(a1 + a2 + a3 + a4)^2 + (b1 + b2 + b3 + b4)^2

//=a1^2 + (a2+a3+a4)^2 + 2*a1*(a2+a3+a4) + b1^2 + 2*b1*(b1+b2+b3)

//每次dfs返回三个数,a,b,c

//a表示个数,b表示所有数的和,c表示所有数的平方和

//那么更新的ans.a += a;

//ans.b +=(b + i*temp_b*a)

//ans.c+=(c + (temp_b*i)^2*a + 2*(temp_b*i)*b)

//其中temp_b为当前数的数量级

#include<cstdio>

#include<cstring>

#include<iostream>

using namespace std ;

const int maxn = 20 ;

const int mod_m = 1e9 + 7;

struct node

{

__int64 a , b , c;//a表示个数,b表示所有数的和,c表示所有数的平方和

} dp[maxn][10][10*maxn][2][2];

void equal(node &t1 ,node &t2)

{

t1.a = t2.a;

t1.b = t2.b;

t1.c = t2.c;

}

int bit[maxn] ;

__int64 pow(__int64 a ,__int64 b)

{

__int64 c = 1;

while(b)

{

if(b & 1) c = ((c%mod_m) * (a%mod_m))%mod_m ;

a = ((a%mod_m) * (a%mod_m))%mod_m ;

b >>= 1;

}

return c;

}

node dfs(int pos,int mod ,int sum ,int flag ,int lim )

{

if(dp[pos][mod][sum][flag][lim].a != -1)

return dp[pos][mod][sum][flag][lim];

int num = lim ? bit[pos] : 9 ;

struct node ans = {0,0,0};

__int64 temp_c = (pow(10,pos-1) * pow(10 , pos-1)) % mod_m ;

__int64 temp_b = pow(10 , pos-1) ;

for(int i = 0;i <= num ;i++)

{

int mod_x = (mod*10 + i) % 7;

int sum_x = sum + i ;

int flag_x = flag;

if(i == 7)

flag_x = 1;

if(pos == 1)

{

if(!flag_x && mod_x!= 0 && (sum_x%7) != 0)

{

ans.a += 1;

ans.b += i;

ans.c += i*i;

}

continue ;

}

struct node now = dfs(pos - 1, mod_x ,sum_x ,flag_x ,lim&&(i == num));

__int64 a = now.a % mod_m;

__int64 b = now.b % mod_m;

__int64 c = now.c % mod_m;

ans.c = (ans.c+c)%mod_m;

ans.c = (ans.c + (((((a*temp_c)%mod_m)*(__int64)i)%mod_m)*i)%mod_m)%mod_m;

ans.c = (ans.c + 2*(((b*temp_b)%mod_m)*(__int64)i)%mod_m)%mod_m;

ans.b = (ans.b + ((__int64)i*((temp_b*a)%mod_m) + b)%mod_m) % mod_m;

ans.a = (ans.a+a)%mod_m;

}

equal(dp[pos][mod][sum][flag][lim] ,ans) ;

return ans;

}

__int64 solve(__int64 n)

{

if(n==0)return 0;

memset(dp , -1 ,sizeof(dp)) ;

int len = 0;

while(n)

{

bit[++len] = n%10;

n/=10;

}

struct node now = dfs(len , 0 ,0 , 0 ,1 ) ;

return now.c ;

}

int main()

{

int T ;__int64 L , R;

scanf("%d" ,&T) ;

while(T--)

{

scanf("%I64d%I64d" ,&L ,&R) ;

printf("%I64d\n" ,(solve(R) - solve(L-1)+mod_m)%mod_m) ;

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: