您的位置:首页 > 其它

HDU4507 恨7不成妻【数位dp】

2019-03-13 12:08 10 查看
版权声明:----------------------------------------转载是ok的,但要附上出处哟 https://blog.csdn.net/qq_43040655/article/details/88529724

传送门

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

loc: 当前位置
q:当前数位的数字
a:之前满足条件的数
b:当前满足条件的数
b=q∗10loc−1+ab= q*10^{loc-1}+ab=q∗10loc−1+a
b2=(q∗10loc−1+a)2b^2=(q*10^{loc-1}+a)^2b2=(q∗10loc−1+a)2

∑(a+b)2=∑a2+∑b2+∑2∗a∗b\sum (a+b)^2=\sum a^2+ \sum b^2+ \sum 2*a*b∑(a+b)2=∑a2+∑b2+∑2∗a∗b

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

Ps[loc]=Ps[loc−1]+m[loc−1]∗q2+2∗q∗s[loc−1] Ps[loc]= Ps[loc-1]+m[loc-1]*q^2+2*q*s[loc-1]Ps[loc]=Ps[loc−1]+m[loc−1]∗q2+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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: