题目链接: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. 对原型prototype的详解

    刚开始接触对象原型时大脑就开始起义了,脑子就转不灵清了.就感觉怎么着这个概念就是灌输不进去,俗称断路.后面找了很多资料,最主要的还是要借助于<JavaScript语言精髓>这本书,让我对这 ...

  2. 混合高斯模型和EM

    <统计学习方法>这本书上写的太抽象,可参考这位大神的:http://www.cnblogs.com/jerrylead/archive/2011/04/06/2006924.html

  3. PHP网页数据正则采集

    $url ="https://********"; $contents = file_get_contents($url); //抓取页面数据 //如果出现中文乱码使用下面代码 / ...

  4. 用JAVA代码实现验证邮箱地址是否符合

    public class Test{ public static void main(String[] args){ Test t = new Test(); String email = " ...

  5. 如何实现SSH断开后 进程仍然在后台运行

    1.nohup命令功能:不挂断地运行命令,忽略HUP信号.语法:nohup command & 实例:nohup ping www.google.com & 转自: http://bl ...

  6. sharepoint添加应用程序

  7. 38.输出1到最大的N位数[Print 1 to max number of N bits]

    [题目] 输入数字n,按顺序输出从1最大的n位10进制数.比如输入3,则输出1.2.3一直到最大的3位数即999. [分析] 这是一道很有意思的题目.看起来很简单,其实里面却有不少的玄机. [常规思路 ...

  8. 如何给spine骨骼动画挂载粒子特效

    目的是要把粒子挂载到骨骼动画的某个一个部件上,其实最主要是找对位置. 预览效果,左手红火,右手蓝火,很炫吧:) //init bool HelloWorld::init() { /////////// ...

  9. 用php实现遍历目录

    用php实现的遍历目录,只遍历第一层,如果制作在线文件管理器的话很管用,不同目录只加一个超链接就行了,然后给方法传递参数就行了,遍历目录的类如下: class Ergodic{ public func ...

  10. 17.Python笔记之memcached&redis

    作者:刘耀 博客:www.liuyao.me 博客园:www.cnblogs.com/liu-yao 一.Memcached 1.介绍 Memcached 是一个高性能的分布式内存对象缓存系统,用于动 ...