【HDU4507】恨7不成妻(数位DP)
大致题意: 让你求出一段区间内与\(7\)无关的数的平方和。与\(7\)无关的数指整数中任意一位不为\(7\)、整数的每一位加起来的和不是\(7\)的整数倍、这个整数不是\(7\)的倍数。
数位\(DP\)
这题应该比较显然是一道 数位\(DP\) 题。
如何记录状态
这道题关键就在于如何记录状态,其余的就和普通的数位\(DP\)差不多了。
我们可以用\(f_{x,s1,s2}\)来表示还剩\(x\)位,这个数除末\(x\)位以外模\(7\)余\(s1\),这个数每一位之和除末\(x\)位以外模\(7\)余\(s2\)时所有与\(7\)无关的数的末\(x\)位的平方和。
但是,如果光光记录平方和,转移就有点困难了。
所以,我们先要来一点恶心的数学转化。
数学转化
让我们来研究一下\((x_1+t*10^y)^2+(x_2+t*10^y)^2+...+(x_n+t*10^y)^2\)这个式子。
先由完全平方公式可得:
\]
然后,我们将其去括号并重新组合,可得:
\]
如果用\(f(n)\)来表示\(x_1+x_2+...+x_n\),\(f^2(n)\)来表示\(x_1^2+x_2^2+...+x_n^2\),则:
\]
我们可以预处理出\(10^y\),并对于每个状态记录下\(n,f(n)\)和\(f^2(n)\),这样就可以实现\(O(1)\)转移了。
状态转移方程
用\(ns1\)来表示\((s1*10+i)\)%\(y\),\(ns2\)来表示\((s2+i)\)%\(y\)。
\]
\]
\]
代码
#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define uint unsigned int
#define LL long long
#define ull unsigned long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define abs(x) ((x)<0?-(x):(x))
#define INF 1e9
#define Inc(x,y) ((x+=y)>=MOD&&(x-=MOD))
#define MOD 1000000007
using namespace std;
LL n,m;
class FIO
{
private:
#define Fsize 100000
#define tc() (FinNow==FinEnd&&(FinEnd=(FinNow=Fin)+fread(Fin,1,Fsize,stdin),FinNow==FinEnd)?EOF:*FinNow++)
#define pc(ch) (FoutSize<Fsize?Fout[FoutSize++]=ch:(fwrite(Fout,1,FoutSize,stdout),Fout[(FoutSize=0)++]=ch))
LL f,FoutSize,OutputTop;char ch,Fin[Fsize],*FinNow,*FinEnd,Fout[Fsize],OutputStack[Fsize];
public:
FIO() {FinNow=FinEnd=Fin;}
inline void read(LL &x) {x=0,f=1;while(!isdigit(ch=tc())) f=ch^'-'?1:-1;while(x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));x*=f;}
inline void read_char(char &x) {while(isspace(x=tc()));}
inline void read_string(string &x) {x="";while(isspace(ch=tc()));while(x+=ch,!isspace(ch=tc())) if(!~ch) return;}
inline void write(LL x) {if(!x) return (void)pc('0');if(x<0) pc('-'),x=-x;while(x) OutputStack[++OutputTop]=x%10+48,x/=10;while(OutputTop) pc(OutputStack[OutputTop]),--OutputTop;}
inline void write_char(char x) {pc(x);}
inline void write_string(string x) {register LL i,len=x.length();for(i=0;i<len;++i) pc(x[i]);}
inline void end() {fwrite(Fout,1,FoutSize,stdout);}
}F;
class Class_DigitalDP
{
private:
#define ten(x) ((x<<3)+(x<<1))
LL ans,len,num[20],tn[20];
struct key//记录一个状态
{
LL res,res_,tot;//res记录平方和,res_记录和,tot记录个数
key(LL x=0,LL y=0,LL z=-1):res(x%MOD),res_(y%MOD),tot(z%MOD){}
}f[20][7][7];
inline void Init(LL x) {len=0;while(x) num[++len]=x%10,x/=10;num[len+1]=0;}
inline key dfs(LL x,LL s1,LL s2,LL flag)
{
register LL i,lim=9,k;register key w=key(0,0,0),t;//w记录结果
if(!x) return key(0,0,s1&&s2);//如果x为0,返回结果
if(flag&&~f[x][s1][s2].tot) return f[x][s1][s2];//如果当前状态肯定在求解范围内,且已经访问并求解过当前状态,返回上次求解得到的答案
if(!flag) (num[x]^7&&(t=dfs(x-1,(ten(s1)+num[x])%7,(s2+num[x])%7,0),k=num[x]*tn[x-1]%MOD,w=key(t.res+(t.res_<<1)*k%MOD+t.tot*k%MOD*k%MOD,t.res_+t.tot*k%MOD,t.tot),true)),lim=num[x]-1;//对于不一定在求解范围内的值特殊处理
for(i=0;i<=lim;++i) if(i^7) t=dfs(x-1,(ten(s1)+i)%7,(s2+i)%7,1),k=i*tn[x-1]%MOD,w=key(w.res+t.res+(t.res_<<1)*k%MOD+t.tot*k%MOD*k%MOD,w.res_+t.res_+t.tot*k%MOD,w.tot+t.tot);//对每一个不为7的数字进行状态转移
if(flag) f[x][s1][s2]=w;//如果当前状态肯定在求解的范围内,就将求解出的答案记录下来,实现记忆化
return w;//返回求解出的答案
}
public:
Class_DigitalDP() {tn[0]=1;for(register LL i=1;i<20;++i) tn[i]=ten(tn[i-1])%MOD;}//预处理出10的幂
inline LL GetAns(LL x) {return !x?0:((void)(Init(x)),dfs(len,0,0,0).res);}//求解答案
}DigitalDP;
int main()
{
register LL i;register LL T;F.read(T);
while(T--) F.read(n),F.read(m),F.write(((DigitalDP.GetAns(m)-DigitalDP.GetAns(n-1))%MOD+MOD)%MOD),F.write_char('\n');
return F.end(),0;
}
【HDU4507】恨7不成妻(数位DP)的更多相关文章
- hdu4507吉哥系列故事——恨7不成妻 (数位dp)
Problem Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: ...
- HDU-4507 吉哥系列故事——恨7不成妻 数位DP
题意:给定区间[L, R]求区间内与7无关数的平方和.一个数当满足三个规则之一则认为与7有关:1.整数中某一位是7:2.整数的每一位加起来的和是7的整数倍:3.这个整数是7的整数倍: 分析:初看起来确 ...
- hdu-4507 吉哥系列故事——恨7不成妻 数位DP 状态转移分析/极限取模
http://acm.hdu.edu.cn/showproblem.php?pid=4507 求[L,R]中不满足任意条件的数的平方和mod 1e9+7. 条件: 1.整数中某一位是7:2.整数的每一 ...
- 【hdu4507】吉哥系列故事——恨7不成妻 数位dp
题目描述 求 $[L,R]$ 内满足:数位中不包含7.数位之和不是7的倍数.本身不是7的倍数 的所有数的平方和 mod $10^9+7$ . 输入 输入数据的第一行是case数T(1 <= T ...
- hdu4507 吉哥系列故事——恨7不成妻[数位DP]
这题面什么垃圾玩意儿 首先看到问题格式想到数位DP,但是求的是平方和.尝试用数位DP推出. 先尝试拼出和.设$f[len][sum][mod]$表示填到$len$位,已填位置数位和$sum$,数字取余 ...
- 吉哥系列故事——恨7不成妻(数位DP)
吉哥系列故事——恨7不成妻 http://acm.hdu.edu.cn/showproblem.php?pid=4507 Time Limit: 1000/500 MS (Java/Others) ...
- 几道数位DP
因为这几天写的几道数位DP大多都太水..而且也确实没什么好讲所以就扔到一起了. [hdu4772]Good Numbers 要求统计区间内 各位数之和能被10整除 的数的个数. 练手,f[i][j][ ...
- 数位DP复习笔记
前言 复习笔记第五篇.(由于某些原因(见下),放到了第六篇后面更新)CSP-S RP++. luogu 的难度评级完全不对,所以换了顺序,换了别的题目.有点乱,见谅.要骂就骂洛谷吧,原因在T2处 由于 ...
- 「算法笔记」数位 DP
一.关于数位 dp 有时候我们会遇到某类问题,它所统计的对象具有某些性质,答案在限制/贡献上与统计对象的数位之间有着密切的关系,有可能是数位之间联系的形式,也有可能是数位之间相互独立的形式.(如求满足 ...
- 2018.09.27 hdu4507吉哥系列故事——恨7不成妻(数位dp)
传送门 一道比较综合的数位dp. 维护三个值:[L,R][L,R][L,R] 区间中与7无关的数的数量,与7无关的数之和,与7无关的数的的平方和. 然后可以用第一个值推第二个,第一个和第二个值推第三个 ...
随机推荐
- Codeforces Round #527 (Div. 3)C(多重集,STRING)
#include<bits/stdc++.h>using namespace std;const int maxn=1e6+7;pair<string,int>p[maxn]; ...
- 查询缓存及索引:MySQL系列之九
一.MySQL的架构 连接器 连接池,安全认证.线程池.连接限制.检查内存.缓存 SQL接口 DML.DDL SQL解析器,对SQL语句的权限检查.解析为二进制程序 优化器,优化访问路径 缓存cach ...
- spring retry注解
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- Windows下搭建QT环境
必须软件 qt-windows-opensource-5.1.1-msvc2010-x86-offline qt-vs-addin-1.2.2-opensource支持vs2008.2010.2012 ...
- 004 Median of Two Sorted Arrays 两个有序数组的中位数
There are two sorted arrays nums1 and nums2 of size m and n respectively.Find the median of the two ...
- WebP图片格式
腾讯科技讯 科技博客GigaOM近日撰文称,谷歌(微博)试图让WebP图片格式取代JPEG等现有图片格式.虽然谷歌无法很快达成所愿,但WebP仍然会对互联网产生重大影响. 文章全文如下: 受够了 ...
- powerdesigner添加唯一约束
假设我们有一个user表,字段为ID和NAME,现在ID作为逻辑主键,自增,想将NAME添加唯一约束,话不多说直接上图: # 添加一个key, 名字随便取,我取为key_u # 双击添加的key的第一 ...
- postgresql导出某张表的数据
\copy 表名 to 路径 with csv 比如: \copy dataset to /home/backup/dataset.csv with csv \copy dataset to /hom ...
- 2016年5月8日 GDCPC省赛总结
入坑ACM半年多了,从开始的a+b,到现在,懵懵懂懂地去参加了省赛......成绩虽然不是特别好,但希望自己能坚持下去吧,肯付出不一定有收获,但是不付出就一定没有收获啦!而且我也挺喜欢ACM的,最起码 ...
- HTML常用标签参考学习
1.跑马灯标签 功能<marquee>...</marquee> 普通卷动<marquee behavior=slide>...</marquee> 滑 ...