HDU4507 恨7不成妻【数位dp】

版权声明:----------------------------------------转载是ok的,但要附上出处哟 https://blog.csdn.net/qq_43040655/article/details/88529724

传送门


思路:
比较基础的一道数位dp,只是平方和的维护要思考一下

loc: 当前位置
q:当前数位的数字
a:之前满足条件的数
b:当前满足条件的数
b = q 1 0 l o c 1 + a b= q*10^{loc-1}+a
b 2 = ( q 1 0 l o c 1 + a ) 2 b^2=(q*10^{loc-1}+a)^2

( a + b ) 2 = a 2 + b 2 + 2 a b \sum (a+b)^2=\sum a^2+ \sum b^2+ \sum 2*a*b

m:满足条件的数的个数
s:所有满足条件的数的总和
Ps:所有满足条件的数的平方和

P s [ l o c ] = P s [ l o c 1 ] + m [ l o c 1 ] q 2 + 2 q s [ l o c 1 ] Ps[loc]= Ps[loc-1]+m[loc-1]*q^2+2*q*s[loc-1]
(注意取模)


代码:

#include<bits/stdc++.h>
using namespace std;
#define sf scanf
#define pf printf
#define int long long
const int mod=1e9+7;
struct node{
	int m,s,p;
	node operator +(const node & t ) const{
		return node((m+t.m)%mod,(s+t.s)%mod,(p+t.p)%mod);
	}
	node (int m=-1,int s=-1,int p=-1): m(m),s(s),p(p) {}
}f[20][10][10];
int bit[20],top=0,fc[20];
inline node update(node t,int q){
//	pf("t   m: %d s: %d p:%d q:%d \n",t.m,t.s,t.p,q);
	node ret;
	ret.m=t.m;
	ret.s= (q*t.m%mod+t.s)%mod;
	ret.p=t.p+t.m*(q*q%mod)%mod+2*t.s*q%mod;
	ret.p%=mod;
//	pf("ret m: %d s: %d p:%d q:%d \n",ret.m,ret.s,ret.p,q);
//	cout<<"\n";
	return ret;
}
inline node check(int sm,int om){
	if(sm%7!=0&&om%7!=0){
		return node(1,0,0);
		//return node(1,ori,ori*ori%mod);
	}
	return node(0,0,0);
}
inline node dfs(int loc,int sm,int om,bool up){
//	pf("loc: %d sm: %d om: %d up:%d ori: %d\n",loc,sm,om,up,ori);
	if(loc==0) return check(sm,om);
	if(!up&&(f[loc][sm][om].m!=-1))return f[loc][sm][om];
	node ret;ret.m=ret.s=ret.p=0;
	int mx=(up)? bit[loc] : 9;
	for(int i=0;i<=mx;++i){
		if(i==7)continue;
		ret=ret+update(dfs(loc-1,(sm+i)%7,(om*10+i)%7,up&&i==mx),i*fc[loc-1]%mod);
//		pf("loc: %d round : %d \n ret m: %d s: %d p:%d \n",loc,i,ret.m,ret.s,ret.p);
	}
	return (up) ?  ret  :  f[loc][sm][om]=ret; 
}
inline int work(int R){
	top=0;
	while(R)bit[++top]=R%10,R/=10;
	return dfs(top,0,0,1).p;
}
signed main(){
	int t,l,r;sf("%I64d",&t);
	fc[0]=1;for(int i=1;i<=18;++i) fc[i]=fc[i-1]*10;
	while(t--){
		sf("%I64d%I64d",&l,&r);
		cout<<(work(r)-work(l-1)+mod)%mod<<"\n";
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_43040655/article/details/88529724