HDU 4507 吉哥系列故事——恨7不成妻 【数位DP】
2016-11-05 11:21
417 查看
题目:点击打开链接
题意:中文题
分析:由于题目要求的是区间内的满足条件的数的平方之和,所以不能用传统的只记录个数来做了。构造结构体记录数的个数,总和以及平方和。dp[pos][sta][smod][mod],sta表示数位是否存在7,smod表示当前的数对7取模的值,mod表示当前的数的每一个数位之和对7取模的值,易得出数的个数。然后可以通过数的个数,算出数的总和。
令pre=(先前数位的值)*(所在数位位置的十进制基数),tmp表示先前的各个满足条件的数,cnt表示先前数位的满足条件的数的个数,sum表示先前数位的数的个数,sq表示先前数位的数的平方之和。∑表示cnt个数值连加。
sum=∑tmp,
sq=∑tmp²,
cnt[new]=cnt[old]+cnt,
sum[new]=sum[old]+∑(tmp+pre)=sum[old]+∑tmp+cnt*pre=sum[old]+sum+cnt*pre,
sq[new]=sq[old]+∑(pre+tmp)²=sq[old]+∑(pre²+2*pre*tmp+tmp²)=sq[old]+cnt*pre²+2*pre*∑tmp+∑tmp²=sq[old]+cnt*pre²+2*pre*sum+sq,因此求出所有数平方之和了。
题意:中文题
分析:由于题目要求的是区间内的满足条件的数的平方之和,所以不能用传统的只记录个数来做了。构造结构体记录数的个数,总和以及平方和。dp[pos][sta][smod][mod],sta表示数位是否存在7,smod表示当前的数对7取模的值,mod表示当前的数的每一个数位之和对7取模的值,易得出数的个数。然后可以通过数的个数,算出数的总和。
令pre=(先前数位的值)*(所在数位位置的十进制基数),tmp表示先前的各个满足条件的数,cnt表示先前数位的满足条件的数的个数,sum表示先前数位的数的个数,sq表示先前数位的数的平方之和。∑表示cnt个数值连加。
sum=∑tmp,
sq=∑tmp²,
cnt[new]=cnt[old]+cnt,
sum[new]=sum[old]+∑(tmp+pre)=sum[old]+∑tmp+cnt*pre=sum[old]+sum+cnt*pre,
sq[new]=sq[old]+∑(pre+tmp)²=sq[old]+∑(pre²+2*pre*tmp+tmp²)=sq[old]+cnt*pre²+2*pre*∑tmp+∑tmp²=sq[old]+cnt*pre²+2*pre*sum+sq,因此求出所有数平方之和了。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <stdio.h> #include <iostream> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <set> #include <vector> #include <map> #define sqr(x) ((x)*(x)) #define PR pair<int,int> #define MP make_pair #define fi first #define se second #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define ll long long const ll INF = 1e18; const int inf=0x3f3f3f3f; const int M=100010; const int N=15; const ll MOD=1000000007; const double eps=1e-8; const double pi=acos(-1.0); using namespace std; ll l,r,hsh[20]; int dig[20],vis[20][2][7][7]; struct node { ll cnt,sum,sq; node(ll _cnt=0,ll _sum=0,ll _sq=0):cnt(_cnt),sum(_sum),sq(_sq){}; }dp[20][2][7][7]; void init() { hsh[0]=1; for(int i=1;i<20;i++) hsh[i]=hsh[i-1]*10%MOD; } node dfs(int pos,int sta,int smod,int mod,int lim) { if(pos==0) return node(sta==0&&smod&&mod,0,0); if(!lim&&vis[pos][sta][smod][mod]) return dp[pos][sta][smod][mod]; int upper=lim?dig[pos]:9; node nxt,res; for(int i=0;i<=upper;i++) { nxt=dfs(pos-1,sta||(i==7),(smod*10+i)%7,(mod+i)%7,lim&&(i==upper)); ll pre=i*hsh[pos-1]%MOD; res.cnt=(res.cnt+nxt.cnt)%MOD; res.sum=(res.sum+nxt.sum+pre*nxt.cnt)%MOD; res.sq=(res.sq+nxt.sq+pre*pre%MOD*nxt.cnt+2*pre*nxt.sum)%MOD; } if(!lim) { vis[pos][sta][smod][mod]=1; dp[pos][sta][smod][mod]=res; } return res; } ll calc(ll x) { int len=0; while(x) { dig[++len]=x%10; x/=10; } return dfs(len,0,0,0,1).sq; } int main() { init(); int T; scanf("%d",&T); while(T--) { scanf("%I64d%I64d",&l,&r); printf("%I64d\n",(calc(r)-calc(l-1)+MOD)%MOD); } }
相关文章推荐
- hdu 4507 吉哥系列故事——恨7不成妻(数位DP,5级)
- HDU 4507 吉哥系列故事——恨7不成妻(数位DP)
- HDU 4507 吉哥系列故事——恨7不成妻(数位DP)
- Hdu 4507 吉哥系列故事——恨7不成妻 (数位DP)
- HDU - 4507 吉哥系列故事――恨7不成妻 (数位DP)
- Hdu 4507 吉哥系列故事——恨7不成妻(求平方和的数位dp)
- HDU 4507 吉哥系列故事——恨7不成妻(数位DP)
- 数位dp_HDU_4507_吉哥系列故事——恨7不成妻
- HDU 4507 吉哥系列故事 恨7不成妻 (数位dp)
- [数位dp] hdu 4507 吉哥系列故事——恨7不成妻
- HDU 4507 吉哥系列故事——恨7不成妻(数位DP)
- HDU 4507 吉哥系列故事——恨7不成妻 数位DP
- hdu 4507 - 吉哥系列故事——恨7不成妻(数位dp)
- 【HDU】4507 吉哥系列故事——恨7不成妻 数位DP
- [HDU 4507] 吉哥系列故事——恨7不成妻 数位dp
- HDU 4507 吉哥系列故事——恨7不成妻 (数位DP)
- HDU-4507 吉哥系列故事——恨7不成妻 数位DP
- hdu 4507 吉哥系列故事——恨7不成妻 (数位dp)
- hdu_4507_吉哥系列故事——恨7不成妻(鬼畜数位DP)
- hdu 4507 吉哥系列故事――恨7不成妻 数位dp