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

/*
http://hi.baidu.com/longmenwaideyu/item/0fc75b2897e0430276272c85
*/

#include<stdio.h>

typedef __int64 lld;
const int mod=1000000007;

struct Node{
	lld s,n,sq;	
	Node(lld a=0,lld b=0,lld c=0):s(a),n(b),sq(c){}
}dp[20][7][7];
lld ten[20];
int bit[20];

/*
dp[i][j][k]表示没边界的i位数,在i位前的那几位数字和对7取余为j,
在i位前的那几位数对7取余为k的总数dp;
在i位前几位可以通过dp值枚举,后面的用dp记录其和,数量,平方和
*/
Node dfs(int pos,int flag,int p,int q){
	Node ret;
	if(pos==0){
		if(p && q)ret.n=1;
		return ret;
	}
	if(!flag && dp[pos][p][q].n!=-1)return dp[pos][p][q];
	int end=flag?bit[pos]:9;
	for(int i=0;i<=end;i++){
		if(i==7)continue;
		int a=(p+i)%7;
		int b=(q*10+i)%7;
		Node tp=dfs(pos-1,flag && i==end,a,b);
		ret.n=(ret.n+tp.n)%mod;
		ret.s=(ret.s+tp.s+i*ten[pos]*tp.n)%mod;

		ret.sq=(ret.sq+tp.sq)%mod;
		ret.sq=(ret.sq+((2*i*ten[pos])%mod)*tp.s%mod)%mod;

		lld t=i*ten[pos]%mod;
		ret.sq=(ret.sq+tp.n*(t*t%mod)%mod)%mod;
	}
	if(!flag)dp[pos][p][q]=ret;
	return ret;
}

lld Cal(lld n){
	lld pos=1;
	while(n){
		bit[pos++]=n%10;
		n/=10;
	}
	Node ret=dfs(pos-1,1,0,0);
	return ret.sq;
}
void init(){
	int i,j,k;
	ten[0]=ten[1]=1;
	for(i=2;i<20;i++)
		ten[i]=ten[i-1]*10%mod;
	for(i=0;i<20;i++)
		for(j=0;j<7;j++)
			for(k=0;k<7;k++)
				dp[i][j][k].n=-1;
}

int main(){
	int T;
	lld a,b;
	scanf("%d",&T);
	init();
	while(T--){
		scanf("%I64d%I64d",&a,&b);
		lld ans=Cal(b)-Cal(a-1);
		if(ans<0)ans+=mod;
		printf("%I64d\n",ans);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值