hdu4507
数位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的更多相关文章
- [HDU4507]吉哥系列故事——恨7不成妻
[HDU4507]吉哥系列故事--恨7不成妻 试题描述 单身!依然单身!吉哥依然单身!DS级码农吉哥依然单身!所以,他生平最恨情人节,不管是214还是77,他都讨厌!吉哥观察了214和77这两个数,发 ...
- HDU-4507 吉哥系列故事——恨7不成妻 数位DP
题意:给定区间[L, R]求区间内与7无关数的平方和.一个数当满足三个规则之一则认为与7有关:1.整数中某一位是7:2.整数的每一位加起来的和是7的整数倍:3.这个整数是7的整数倍: 分析:初看起来确 ...
- hdu4507 数位dp+推公式
推公式的能力需要锻炼.. /* dp的时候要存结构体 里面三个元素: cnt,就是满足条件的个数 sum1,就是满足条件的数字和 sum2,满足条件的数字平方和 推导过程:还是用记忆化搜索模板 dp[ ...
- 【HDU4507】恨7不成妻
Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: 2+1+4=7 ...
- hdu-4507 吉哥系列故事——恨7不成妻 数位DP 状态转移分析/极限取模
http://acm.hdu.edu.cn/showproblem.php?pid=4507 求[L,R]中不满足任意条件的数的平方和mod 1e9+7. 条件: 1.整数中某一位是7:2.整数的每一 ...
- 2018.09.27 hdu4507吉哥系列故事——恨7不成妻(数位dp)
传送门 一道比较综合的数位dp. 维护三个值:[L,R][L,R][L,R] 区间中与7无关的数的数量,与7无关的数之和,与7无关的数的的平方和. 然后可以用第一个值推第二个,第一个和第二个值推第三个 ...
- 【hdu4507】吉哥系列故事——恨7不成妻 数位dp
题目描述 求 $[L,R]$ 内满足:数位中不包含7.数位之和不是7的倍数.本身不是7的倍数 的所有数的平方和 mod $10^9+7$ . 输入 输入数据的第一行是case数T(1 <= T ...
- 【HDU4507】恨7不成妻(数位DP)
点此看题面 大致题意: 让你求出一段区间内与\(7\)无关的数的平方和.与\(7\)无关的数指整数中任意一位不为\(7\).整数的每一位加起来的和不是\(7\)的整数倍.这个整数不是\(7\)的倍数. ...
- hdu4507(数位DP)
题目意思: 给定一个区间,求这段区间中,不含7,对7取余为0,各个位数相加之和对7取余为0的数的平方和. 设d[i][j][k][m]代表长度为i的,对7取余为j的,各个位数相加之和对7取余为k的数的 ...
随机推荐
- 【转】zookeeper 的监控工具
公司很多产品会使用zookeeper,比如Meta消息中间件,在测试的过程中,我们经常需要查询zookeeper里面的信息来精确定位问题.目前项目中有开发团队自己写的浏览器node-z ...
- centOs下的php+mysql+apache+ftp配置
在安装服务器时做了相应的笔记,这个方法是亲身经验成功的,随着版本的不断更新,也许会有一些地方不同,但是基本原理都是一样的. 1.安装CentOS 6 ,可以选择最小安装,也可以安装桌面 2.升级系统 ...
- javase程序设计课后题答案
;第1章 Java概述 编译java application源程序文件将产生相应的字节码文件,这些字节码文件别的扩展名为.java 执行一个java程序fristapp的方法是运行java frist ...
- 【转】Perl Unicode全攻略
Perl Unicode全攻略 耐心看完本文,相信你今后在unicode处理上不会再有什么问题. 本文内容适用于perl 5.8及其以上版本. perl internal form 在Perl看来, ...
- Java数据结构习题_算法分析
2.设T1(N)=O(f(N)),T2(N)=O(f(N)),则: T1(N)-T2(N)=o(f(N)) False,若1位2N,2为N T1(N)/T2(N)=O(1) ...
- Hadoop4Win
Hadoop4Win + Eclipse 运行 WordCount 程序 http://software.intel.com/zh-cn/blogs/2013/10/16/hadoop4win-ecl ...
- 表格无边框,有内框,在table嵌套时,防止出现重复边线
<html> <head> <title>test 表格无边框,有内框! ^^ CSDN 学习积累</title> <style type=&qu ...
- 第52周二Restful
今天去spring官网发现一个关键词:Restful,以前只在与一个系统对接时用到过这种形式的接口,但印象不深,百度搜索后才感觉自己太out了,这个概念2000年提出,2009年时国内就有很多人推荐使 ...
- linux 和unix 的区别
Linux与Unix的区别 某些PC机的Unix和Linux在实现方面相类似.几乎所有的商业Unix版本都基本支持同样的软件.程序设计环境和网络特性.然而,Linux和Unix的商业版本依然存在许多 ...
- poj1007 qsort快排
这道题比较简单,但通过这个题我学会了使用c++内置的qsort函数用法,收获还是很大的! 首先简要介绍一下qsort函数. 1.它是快速排序,所以就是不稳定的.(不稳定意思就是张三.李四成绩都是90, ...