Hdu 4507 吉哥系列故事——恨7不成妻(求平方和的数位dp)
2014-12-04 10:48
519 查看
题目 链接
Total Submission(s): 1752 Accepted Submission(s): 505
[align=left]Problem Description[/align]
单身!
依然单身!
吉哥依然单身!
DS级码农吉哥依然单身!
所以,他生平最恨情人节,不管是214还是77,他都讨厌!
吉哥观察了214和77这两个数,发现:
2+1+4=7
7+7=7*2
77=7*11
最终,他发现原来这一切归根到底都是因为和7有关!所以,他现在甚至讨厌一切和7有关的数!
什么样的数和7有关呢?
如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关——
1、整数中某一位是7;
2、整数的每一位加起来的和是7的整数倍;
3、这个整数是7的整数倍;
现在问题来了:吉哥想知道在一定区间内和7无关的数字的平方和。
[align=left]Input[/align]
输入数据的第一行是case数T(1 <= T <= 50),然后接下来的T行表示T个case;每个case在一行内包含两个正整数L, R(1 <= L <= R <= 10^18)。
[align=left]Output[/align]
请计算[L,R]中和7无关的数字的平方和,并将结果对10^9 + 7 求模后输出。
[align=left]Sample Input[/align]
[align=left]Sample Output[/align]
题意:
如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关——
1、整数中某一位是7;
2、整数的每一位加起来的和是7的整数倍;
3、这个整数是7的整数倍;
现在问题来了:吉哥想知道在一定区间内和7无关的数字的平方和。
题解:采用记忆化搜索的方法。
用dp[i][0,1][j][k]表示高于i位的位,是否包含7,每一位加起来的和模7的值为j,高于i位的组成的数模7的值为k,第i位至第0位任意填,该状态下最终会到大目标状态的数的个数(num),数的和(sum),数的平方和(psum)。
转移:若dp[i][e][j][k],第i位填x后,转移到状态dp[i-1][ee][jj][kk]
dp[i][e][j][k].num+=dp[i-1][ee][jj][kk].num;
dp[i][e][j][k].sum+=dp[i-1][ee][jj][kk].sum+x*10^i*dp[i-1][ee][jj][kk].num;
dp[i][e][j][k].psum+=dp[i-1][ee][jj][kk].psum+(x*10^i)^2*dp[i-1][ee][jj][kk].num+2*x*10^i*dp[i-1][ee][jj][kk].sum;
代码如下:
吉哥系列故事——恨7不成妻
Time Limit: 1000/500 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1752 Accepted Submission(s): 505
[align=left]Problem Description[/align]
单身!
依然单身!
吉哥依然单身!
DS级码农吉哥依然单身!
所以,他生平最恨情人节,不管是214还是77,他都讨厌!
吉哥观察了214和77这两个数,发现:
2+1+4=7
7+7=7*2
77=7*11
最终,他发现原来这一切归根到底都是因为和7有关!所以,他现在甚至讨厌一切和7有关的数!
什么样的数和7有关呢?
如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关——
1、整数中某一位是7;
2、整数的每一位加起来的和是7的整数倍;
3、这个整数是7的整数倍;
现在问题来了:吉哥想知道在一定区间内和7无关的数字的平方和。
[align=left]Input[/align]
输入数据的第一行是case数T(1 <= T <= 50),然后接下来的T行表示T个case;每个case在一行内包含两个正整数L, R(1 <= L <= R <= 10^18)。
[align=left]Output[/align]
请计算[L,R]中和7无关的数字的平方和,并将结果对10^9 + 7 求模后输出。
[align=left]Sample Input[/align]
3 1 9 10 11 17 17
[align=left]Sample Output[/align]
236 221 0
题意:
如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关——
1、整数中某一位是7;
2、整数的每一位加起来的和是7的整数倍;
3、这个整数是7的整数倍;
现在问题来了:吉哥想知道在一定区间内和7无关的数字的平方和。
题解:采用记忆化搜索的方法。
用dp[i][0,1][j][k]表示高于i位的位,是否包含7,每一位加起来的和模7的值为j,高于i位的组成的数模7的值为k,第i位至第0位任意填,该状态下最终会到大目标状态的数的个数(num),数的和(sum),数的平方和(psum)。
转移:若dp[i][e][j][k],第i位填x后,转移到状态dp[i-1][ee][jj][kk]
dp[i][e][j][k].num+=dp[i-1][ee][jj][kk].num;
dp[i][e][j][k].sum+=dp[i-1][ee][jj][kk].sum+x*10^i*dp[i-1][ee][jj][kk].num;
dp[i][e][j][k].psum+=dp[i-1][ee][jj][kk].psum+(x*10^i)^2*dp[i-1][ee][jj][kk].num+2*x*10^i*dp[i-1][ee][jj][kk].sum;
代码如下:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<string> #include<queue> #include<stack> #include<map> #include<set> #include<stdlib.h> #include<vector> #define inff 0x3fffffff #define nn 6100 #define mod 1000000007 typedef long long LL; const LL inf64=inff*(LL)inff; using namespace std; LL l,r; struct node { LL num; LL sum; LL psum; void init() { num=sum=psum=0; } }; int wei[20]; LL ni; LL cf(LL x,LL y) { LL tem=x; LL re=1; while(y) { if(y%2) { re=(re*tem)%mod; } tem=(tem*tem)%mod; y/=2; } return re; } node dp[20][2][10][10]; LL po[30]; bool use[20][2][10][10]; node dfs(int id,int qi,int sm,int ssm,bool man) { node re; re.init(); if(id==-1) { if(qi||sm==0||ssm==0) re.num=1; return re; } if(!man&&use[id][qi][sm][ssm]) return dp[id][qi][sm][ssm]; int end=man?wei[id]:9; int i; node ix; for(i=0;i<=end;i++) { if(i==7) ix=dfs(id-1,1,(sm+i)%7,(ssm*10+i)%7,man&&i==end); else ix=dfs(id-1,qi,(sm+i)%7,(ssm*10+i)%7,man&&i==end); re.num=(re.num+ix.num)%mod; re.sum=(re.sum+ix.sum+((ix.num*i)%mod*po[id])%mod)%mod; re.psum=(re.psum+ix.psum)%mod; re.psum=(re.psum+(((po[id]*po[id])%mod*i*i)%mod*ix.num)%mod)%mod; re.psum=(re.psum+((2*po[id]*i)%mod*ix.sum)%mod)%mod; //cout<<re.psum<<" "<<ix.num<<" "<<ix.sum<<" "<<ix.psum<<endl; } if(!man) { use[id][qi][sm][ssm]=true; dp[id][qi][sm][ssm]=re; } return re; } LL solve(LL x) { int ix=0; LL re=x%mod; re=(re*((x+1)%mod))%mod; re=(re*((2*x+1)%mod))%mod; re=(re*ni)%mod; while(x) { wei[ix++]=x%10; x/=10; } return (re-dfs(ix-1,0,0,0,true).psum+mod)%mod; } int main() { int t; memset(use,false,sizeof(use)); ni=cf(6,mod-2); po[0]=1; for(int i=1;i<=20;i++) { po[i]=(po[i-1]*10)%mod; } scanf("%d",&t); while(t--) { scanf("%I64d%I64d",&l,&r); printf("%I64d\n",(solve(r)-solve(l-1)+mod)%mod); } return 0; }
相关文章推荐
- 【数位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)
- [数位dp] hdu 4507 吉哥系列故事——恨7不成妻
- hdu 4507 吉哥系列故事――恨7不成妻 数位dp
- hdu 4507 吉哥系列故事——恨7不成妻(数位DP,5级)
- 数位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)