题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4507

题目大意:求指定范围内与7不沾边的所有数的平方和。结果要mod 10^9+7(鬼畜の元凶)

解题思路

与7不沾边的数需要满足三个条件。

①不出现7

②各位数和不是7的倍数

③这个数不是7的倍数

这三个条件都是基础的数位DP。

但是这题要统计的不是符合条件个数,而是平方和。

也就是说在DP时候,要重建每个数,算出平方,然后求和。

需要维护三个值(推荐使用结构体), 假定dfs推出返回的结构体是next,当前结果的结构体是ans

①符合条件数的个数 cnt

②符合条件数的和 sum

③符合添加数的平方和 sqsum

其中①是基础数位DP。②next.sum+(10^len*i)*ans.cnt,其中(10^len*i)*ans.cnt代表以len为首位的这部分数字和。

③首先重建一下这个数,(10^len*i+x),其中x是这个数的后面部分,则平方和就是(10^len*i)^2+x^2+2*10^len*i*x,其中x^2=next.sqsum

整体还要乘以next.cnt,毕竟不止一个。

这样sqsum+=next.sqsum

sqsum+=(2*10^len*i*x)*next.cnt=(2*10^len*i)*next.sum(神奇的化简)

sqsum+=(10^len*i)^2*next.cnt

然后就是本题鬼畜的地方了,cnt,sum,sqsum,三个都是达到了int64极限。

也即是说凡是这三个值参与运算的地方,都要狠狠打上mod,尤其是cnt!一坨坨mod出现了。

mod之后统计函数也有个小陷阱,那就是f(r)在mod之后有可能小于f(l-1)。也就是要对负数取正数模。

负数取模的方法(ans%mod+mod)%mod。

#include "cstdio"
#include "math.h"
#include "cstring"
#define mod 1000000007LL
#define LL long long
struct status
{
LL cnt,sum,sqsum;
status() {cnt=-;sum=sqsum=;}
status(LL cnt,LL sum,LL sqsum):cnt(cnt),sum(sum),sqsum(sqsum) {}
}dp[][][];
LL digit[],p[];
status dfs(int len,int re1,int re2,bool fp)
{
if(!len) return re1!=&&re2!=?status(,,):status(,,);
if(!fp&&dp[len][re1][re2].cnt!=-) return dp[len][re1][re2];
int fpmax=fp?digit[len]:;
status ans;ans.cnt=;
for(int i=;i<=fpmax;i++)
{
if(i==) continue;
status next=dfs(len-,(re1+i)%,(re2*+i)%,fp&&i==fpmax);
ans.cnt+=next.cnt;
ans.cnt%=mod;
ans.sum+=(next.sum+((p[len]*i)%mod)*next.cnt%mod)%mod;
ans.sum%=mod;
ans.sqsum+=(next.sqsum+((*p[len]*i)%mod)*next.sum)%mod;
ans.sqsum%=mod;
ans.sqsum+=((next.cnt*p[len])%mod*p[len]%mod*i*i%mod);
ans.sqsum%=mod;
}
if(!fp) dp[len][re1][re2]=ans;
return ans;
}
LL f(LL x)
{
int len=;
while(x)
{
digit[++len]=x%;
x/=;
}
status tt=dfs(len,,,true);
return tt.sqsum;
}
int main()
{
int T;
LL l,r;
scanf("%d",&T);
p[]=;
for(int i=;i<=;i++) p[i]=(p[i-]*)%mod;
while(T--)
{
scanf("%I64d%I64d",&l,&r);
LL ans=f(r);
ans-=f(l-);
printf("%I64d\n",(ans%mod+mod)%mod);
}
}
11814266 2014-10-07 00:19:33 Accepted 4507 15MS 276K 1527 B C++ Physcal

HDU 4507 (鬼畜级别的数位DP)的更多相关文章

  1. HDU 5787 K-wolf Number (数位DP)

    K-wolf Number 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5787 Description Alice thinks an integ ...

  2. 【HDU 3652】 B-number (数位DP)

    B-number Problem Description A wqb-number, or B-number for short, is a non-negative integer whose de ...

  3. HDU 5787 K-wolf Number(数位DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5787 [题目大意] 求区间[L,R]内十进制数相邻k位之间不相同的数字的个数. [题解] 很显然的 ...

  4. 2017"百度之星"程序设计大赛 - 复赛1005&&HDU 6148 Valley Numer【数位dp】

    Valley Numer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  5. HDU 4352 XHXJ's LIS 数位dp lis

    目录 题目链接 题解 代码 题目链接 HDU 4352 XHXJ's LIS 题解 对于lis求的过程 对一个数列,都可以用nlogn的方法来的到它的一个可行lis 对这个logn的方法求解lis时用 ...

  6. HDU 2089 不要62(数位dp模板题)

    http://acm.hdu.edu.cn/showproblem.php?pid=2089 题意:求区间内不包含4和连续62的数的个数. 思路: 简单的数位dp模板题.给大家推荐一个好的讲解博客.h ...

  7. hdu 4352 XHXJ's LIS 数位dp+状态压缩

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4352 XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others ...

  8. HDU 2089(暴力和数位dp)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2089 不要62 Time Limit: 1000/1000 MS (Java/Others)    M ...

  9. Hdu 3652 B-number (同余数位DP)

    题目链接: Hdu 3652 B-number 题目描述: 给出一个数n,问 [1, n]区间内有几个数能被13整除并且还有13这个子串? 解题思路: 能整除的数位DP,确定好状态随便搞搞就能过了.d ...

随机推荐

  1. php友好格式化时间

    php格式化时间显示 function toTime($time) {//$time必须为时间戳 $rtime = date("Y-m-d H:i",$time); $htime ...

  2. php __set() __get() __isset() __unset()四个方法的应用

    一般来说,总是把类的属性定义为private,这更符合现实的逻辑.但是,对属性的读取 和赋值操作是非常频繁的,因此在PHP5 中,预定义了两个函数“__get()”和“__set()”来获 取和赋值其 ...

  3. 面向侧面的程序设计AOP-------《二》本质

    本文转载自张逸:晴窗笔记 AOP技术本质 2.2.1 技术概览 AOP(Aspect-Oriented Programming,面向方面编程),可以说是OOP(Object-Oriented Prog ...

  4. 5.前端笔记之jquery部分

    一.简介 jQuery是一个兼容多浏览器的javascript库,核心理念是write less,do more(写得更少,做得更多).jQuery在2006年1月由美国人John Resig在纽约的 ...

  5. DFS:Lake Counting(POJ 2386)

    好吧前几天一直没更新博客,主要是更新博客的确是要耗费一点精力 北大教你数水坑 最近更新博客可能就是一点旧的东西和一些水题,主要是最近对汇编感兴趣了嘻嘻嘻 这一题挺简单的,没什么难度,简单深搜 #inc ...

  6. Gym 100851G Generators (vector+鸽笼原理)

    Problem G. Generators Input file: generators.in Output file: generators.outLittle Roman is studying li ...

  7. Buy Tickets(poj 2828)

    题意:排队买票,但是 中途 出现插队情况,比如 0 123,代表值为123的人 插入到 0 的位置,如果后面 出现 0 456,那么新的 0的位置就是 456,123就变成是 1的位置了 分析:这道题 ...

  8. Http协议之Request和Response

    GET / HTTP/1.1表示向服务器用GET方式请求首页,使用HTTP/1.1协议 Cache-Control作用: 用来指定Response-Request遵循的缓存机制.各个指令含义如下Cac ...

  9. C++复制(拷贝)构造函数详解

    本文转载自 http://blog.csdn.net/lwbeyond/article/details/6202256,在此感谢作者 CTemp B(A);       //复制构造函数,C++风格的 ...

  10. Android之XML序列化和解析

    XML文件是一种常用的文件格式,可以用来存储与传递数据 ,本文是XML文件序列化与解析的一个简单示例 写文件到本地,并用XML格式存储 /** * 写xml文件到本地 */ private void ...