数位dp,终于守得云开见月明了。建议初学者先试试两道比较简单的hdu2089,hdu3555

  鸣谢:http://blog.csdn.net/acm_cxlove/article/details/8707084。

  数位dp也是一种基于状态压缩、优化的动态规划。不同的是,它的压缩和优化往往基于数的一些特性。而数最基本的表现形式:a/b --- [a/b]、[a%b]。

  这种dp才是体现一个人智慧的地方。(额外想为ACM竞赛的同学说两句,个人还是特别顶复旦出题的,至少它出的绝大部分题目都是可以自己通过大学以前的数学知识慢慢想到,而不是像某些学校的题目,只要听说过、学过、看过,某一个不知道哪里冒出来的数学理论就能瞬间AC,否则***。还是不放水了,言归正传)

  本题,中文描述的,不解释了。初学者往往都会往容斥的方面想,(也不是不可以)但其实条件2、条件3的综合比较困难了,代码量和复杂度可能都会很大。

  所以直接递归找跟7有关的数比较科学,假设原数字a+b位,如果搜索前a位fa(fa后b位都是0),后面b位跟7有关的任何一个数x,产生的结果和是(fa+x)^2+x^2。对所有的x,就有{fa^2*cnt(x)+2fa*sum(x)+sum(x^2)=f(a+b,b)}+f(b,0)。这个很容易想到,那么如果搜索时刚好按a从小到大拆分呢?不就是很明显了吗?

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
#define LL long long
const LL mod = 1000000007LL;
#define mp(a,b) make_pair(a,b)
int bit[];
//长度,是否有7,数字和%7,数字%; 数字和、结果和、数字个数
long long s1[][][][],s2[][][][],cnt[][][][];
LL fac[]={};
typedef pair<pair<LL,LL>,LL> pll;
pll DP(int len,int a,int b,int c,int g){
//printf("len = %d, %d, %d, %d, g = %d\n",len,a,b,c,g);
if(g && cnt[len][a][b][c] >= )
return mp(mp(cnt[len][a][b][c],s1[len][a][b][c]),s2[len][a][b][c]);
if(len <= ){
if(b&&c&&!a) cnt[][a][b][c]=;
else cnt[][a][b][c]=;
s1[][a][b][c]=s2[][a][b][c]=;
return mp(mp(cnt[len][a][b][c],s1[len][a][b][c]),s2[len][a][b][c]);
}
int bound=bit[len]; if(g) bound=;
LL tcnt=,ts1=,ts2=;
int nl=len-,na,nb,nc;
for(int i=;i<=bound;i++){
na=(a||i==); nb=(b+i)%; nc=(c*+i)%;
pll p=DP(nl,na,nb,nc,g||(i<bound));
LL f = fac[nl]*i % mod; //f按位拆分,不用靠递归记录!!!
tcnt= (tcnt+p.first.first)%mod;
ts1 = (ts1+p.first.second+p.first.first*f)%mod;
ts2 = (ts2+p.first.first*(f*f%mod)%mod+p.first.second*f*%mod+p.second)%mod;
}
if(g){
cnt[len][a][b][c] = tcnt;
s1[len][a][b][c] = ts1;
s2[len][a][b][c] = ts2;
}
return mp(mp(tcnt,ts1),ts2);
}
LL sum(LL n){
LL a=n,b=n+,c=*n+;
LL x=,y=;
if(a%x==) a/=x,x=;if(a%y==) a/=y,y=;
if(b%x==) b/=x,x=;if(b%y==) b/=y,y=;
if(c%x==) c/=x,x=;if(c%y==) c/=y,y=;
a%=mod;b%=mod;c%=mod;
return (a*b%mod)*c%mod;
}
LL solve(LL n){
if(n <= ) return ;
int len=;
memset(bit,,sizeof(bit));
LL m=n;
while(n > )
bit[++len]=n%, n/=;
//cout<<"n = "<<m<<" ,len = "<<len<<endl;
return ((sum(m)-DP(len,,,,).second)%mod+mod)%mod;
}
int main()
{
for(int i=;i<;i++)
fac[i]=(fac[i-]*)%mod;
memset(cnt,-,sizeof(cnt));
int cases; cin>>cases;
for(int cas=;cas<=cases;cas++){
LL l,r;
cin>>l>>r;
//scanf("%lld%lld",&l,&r);
cout<<((solve(r)-solve(l-))%mod+mod)%mod<<endl;
}
return ;
}

hdu4507的更多相关文章

  1. [HDU4507]吉哥系列故事——恨7不成妻

    [HDU4507]吉哥系列故事--恨7不成妻 试题描述 单身!依然单身!吉哥依然单身!DS级码农吉哥依然单身!所以,他生平最恨情人节,不管是214还是77,他都讨厌!吉哥观察了214和77这两个数,发 ...

  2. HDU-4507 吉哥系列故事——恨7不成妻 数位DP

    题意:给定区间[L, R]求区间内与7无关数的平方和.一个数当满足三个规则之一则认为与7有关:1.整数中某一位是7:2.整数的每一位加起来的和是7的整数倍:3.这个整数是7的整数倍: 分析:初看起来确 ...

  3. hdu4507 数位dp+推公式

    推公式的能力需要锻炼.. /* dp的时候要存结构体 里面三个元素: cnt,就是满足条件的个数 sum1,就是满足条件的数字和 sum2,满足条件的数字平方和 推导过程:还是用记忆化搜索模板 dp[ ...

  4. 【HDU4507】恨7不成妻

    Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: 2+1+4=7 ...

  5. hdu-4507 吉哥系列故事——恨7不成妻 数位DP 状态转移分析/极限取模

    http://acm.hdu.edu.cn/showproblem.php?pid=4507 求[L,R]中不满足任意条件的数的平方和mod 1e9+7. 条件: 1.整数中某一位是7:2.整数的每一 ...

  6. 2018.09.27 hdu4507吉哥系列故事——恨7不成妻(数位dp)

    传送门 一道比较综合的数位dp. 维护三个值:[L,R][L,R][L,R] 区间中与7无关的数的数量,与7无关的数之和,与7无关的数的的平方和. 然后可以用第一个值推第二个,第一个和第二个值推第三个 ...

  7. 【hdu4507】吉哥系列故事——恨7不成妻 数位dp

    题目描述 求 $[L,R]$ 内满足:数位中不包含7.数位之和不是7的倍数.本身不是7的倍数 的所有数的平方和 mod $10^9+7$ . 输入 输入数据的第一行是case数T(1 <= T ...

  8. 【HDU4507】恨7不成妻(数位DP)

    点此看题面 大致题意: 让你求出一段区间内与\(7\)无关的数的平方和.与\(7\)无关的数指整数中任意一位不为\(7\).整数的每一位加起来的和不是\(7\)的整数倍.这个整数不是\(7\)的倍数. ...

  9. hdu4507(数位DP)

    题目意思: 给定一个区间,求这段区间中,不含7,对7取余为0,各个位数相加之和对7取余为0的数的平方和. 设d[i][j][k][m]代表长度为i的,对7取余为j的,各个位数相加之和对7取余为k的数的 ...

随机推荐

  1. HTML5图片预览

    两种方式实现 URL FileReader <!DOCTYPE HTML><html>    <head>    <meta charset="ut ...

  2. LeetCode Day1

    Palindrome Linked List /** * LeetCode: Palindrome Linked List * Given a singly linked list, determin ...

  3. UVA 11175 From D to E and Back

    题意: 给一个n个结点的有向图D,可以构造一个图E:D的每条边对应E的一个结点(例如,若D有一条边uv,则E有个结点的名字叫uv),对于D的两条边uv和vw,E中的两个结点uv和vw之间连一条有向边. ...

  4. RDLC报表系列(二) 行分组

    接上一篇文章的内容,今天来说的是行分组.还是打开demo1.rdlc界面,拖入一个文本框和表 1.在表中随便选择一个字段,不然在添加行组的时候不会自动提示.我这里是选择的Dept 2.在下面的行组中右 ...

  5. 使用UTL_SMTP发送中文电子邮件

    就是在原有TOM源码的基础上修改utl_smtp.write_data中,将输出内容进行一下数据转换,这样可以保证中文输出不会出现乱码 ----------------------------- cr ...

  6. Html遮罩效果

    遮罩效果 <!DOCTYPE html> <html> <head> <title>DIV CSS遮罩层</title> <scrip ...

  7. javascript 里找元素操作元素

      javascript  一.找到元素. var d = document.getElementById("") var d = document.getElementsByNa ...

  8. Unity之GUI控件

    在这里就贴一个连接吧:GUI

  9. memcached的安装和linux下memcached服务自启动的配置

    关于memcached在windows和linux环境的安装,以及在Linux系统系memcached服务自启动的配置,可以参考我在csdn上下的博客, windows和linux环境下memcach ...

  10. linux 系统分区方案建议

    前言: 以前初识Linux时,对Linux系统安装时分区的选择,一点都不了解,导致几次没法进行下一步安装,因此就静下心来,专门拿出时间研究了研究这方面的知识: 以下内容就是以前通过研究Linux安装过 ...