[数位dp] hdu 4507 吉哥系列故事——恨7不成妻

题意:在一定区间内和7无关的数字的平方和。

思路:这种醉醉的题目,也是醉醉的。

其实理解了,就醒了~

首先只求有多少个数,那么大家肯定都会了。

但是这里我们对于dp[site][mod][sum] 要维护3个东西,n:有多少个数、sum:这些数的和、sumqrt这些数的平方和。

我们通过递归,n就是我们大家都会的那个东西,那么对于这些数的和。

举个例子,比如求12

那就是0~12的和。

0:0~9

1:0~2

这两段。

那么我们如果知道0~9的和又知道有10个数 那么他们的和便是 0*10*10+sum(0~9)

然后是0~2的和又知道有3个数  再加上 1*10*3+sum(0~2)  这两个加起来就是0~12的和了

其中0,1就是当前位是什么,10就是对应的10^(site-1),10、3就是多少个数。

想想其实是很好理解的。

那么我们再来看平方和。

为了方便 我们把当前位乘上10对应的次方 设为tep

然后设x1~xn为却掉高位所剩下的数。

那么当前的平方和 就等于 (tep+x1)^2+(tep+x2)^2+...+(tep+xn)^2

展开便是 n*tep^2+2*tep*(x1+x2+..+xn)+(x1^2+x2^2+..+xn^2)  n是个数

那么这样递归下去知道 sum和sumqrt都是一个数 就ok了~

然后就是注意各个地方记得取模 不要溢出了!

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"stack"
#include"algorithm"
#include"iostream"
using namespace std;
int m=1000000007;
struct node
{
    int f;
    __int64 n,sum,sumqrt;
    node()
    {
        f=-1;  //特意弄个f 表示是否记忆过
        n=sum=sumqrt=0;
    }

}dp[22][10][10];
int num[22];
__int64 ten[22];
node dfs(int site,int mod,int sum,int f)
{
    if(site==0)
    {
        node a;
        if(mod!=0&&sum!=0) a.n=1; //到最后如果是 就是一个数~
        return a;
    }
    if(!f&&dp[site][mod][sum].f!=-1) return dp[site][mod][sum];
    int len=f?num[site]:9;
    node cur,next;
    for(int i=0;i<=len;i++)
    {
        if(i==7) continue;
        __int64 tep=i*ten[site]%m;
        cur=dfs(site-1,(mod*10+i)%7,(sum+i)%7,f&&i==len);
        next.n=(next.n+cur.n)%m;
        next.sum=(next.sum+tep*cur.n+cur.sum)%m;
        next.sumqrt=(next.sumqrt+((tep*tep%m)*cur.n)%m+(2*tep*cur.sum)%m+cur.sumqrt)%m;// 注意取模
    }
    if(!f)
    {
        next.f=1;
        dp[site][mod][sum]=next;
    }
    return next;
}
node solve(__int64 x)
{
    int cnt=0;
    while(x)
    {
        num[++cnt]=x%10;
        x/=10;
    }
    return dfs(cnt,0,0,1);
}
int main()
{
    int t;
    cin>>t;
    ten[1]=1;
    for(int i=2;i<=20;i++) ten[i]=(ten[i-1]*10)%m;  //记得取模
    while(t--)
    {
        __int64 x,y;
        __int64 ans=0;
        scanf("%I64d%I64d",&x,&y);
        ans=(solve(y).sumqrt-solve(x-1).sumqrt)%m;
        printf("%I64d\n",(ans+m)%m);  //记得有可能是负数,要化成正的
    }
    return 0;
}
时间: 2024-10-05 22:17:23

[数位dp] hdu 4507 吉哥系列故事——恨7不成妻的相关文章

Hdu 4507 吉哥系列故事——恨7不成妻 (数位DP)

题目链接: Hdu 4507 吉哥系列故事——恨7不成妻 题目描述: 中文题面不描述. 解题思路: 从数据范围可看出是数位DP.根据题目给的限制,如果是求满足限制的数的数目的话,就很简单了.但是这个题目是让求满足题目中限制的数的平方和.我们可以求出区间中满足题目中限制的数的数目,和这些数的和,然后从这两个东西推出这些数的平方和. 假设现在我们已经递归出后面的x-1位满足题目限制的数的数目(num),和(sum),平方和(ssum),当前x位枚举为i,就可以推出当前节点改变为Num += num,

HDU - 4507 吉哥系列故事――恨7不成妻 (数位DP)

Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: 2+1+4=7 7+7=7*2 77=7*11 最终,他发现原来这一切归根到底都是因为和7有关!所以,他现在甚至讨厌一切和7有关的数! 什么样的数和7有关呢? 如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关―― 1.整数中某一位是7: 2.整数的每一位加起来的和是7的整数倍: 3.这个整数是7的整数

HDU 4507 吉哥系列故事――恨7不成妻(数位dp&amp;好魔性的一道好题)

题目链接:[kuangbin带你飞]专题十五 数位DP J - 吉哥系列故事――恨7不成妻 题意 Time Limit:500MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: 2+1+4=7 7+7=7*2 77=7*11 最终,他发现原来这一切归根到底都是

HDU 4507 —— 吉哥系列故事――恨7不成妻

吉哥系列故事――恨7不成妻 Time Limit:500MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 单身!  依然单身!  吉哥依然单身!  DS级码农吉哥依然单身!  所以,他生平最恨情人节,不管是214还是77,他都讨厌!    吉哥观察了214和77这两个数,发现:  2+1+4=7  7+7=7*2  77=7*11  最终,他发现原来这一切归根到底都是因为和7有关!所以,他现在甚至讨

HDU 4507 吉哥系列故事——恨7不成妻 (数位DP)

题意: 如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关: 1.整数中某一位是7: 2.整数的每一位加起来的和是7的整数倍: 3.这个整数是7的整数倍: 给定一个区间[L,R],问在此区间内和7无关的所有数字的平方和. 思路: 第一步好解决,只是数位DP的基础.第二步是十进制的所有位加起来是7的整数倍,这个只是需要用多一维来记录%7的结果就行了.第三步是7的整数倍问题,假设c=a+b,那么c%7=(a%7+b)%7,就假设这个数是10086,那么(10000%7+86)%7就行了,

HDU - 4507 - 吉哥系列故事——恨7不成妻(数位DP,数学)

链接: https://vjudge.net/problem/HDU-4507 题意: 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: 2+1+4=7 7+7=72 77=711 最终,他发现原来这一切归根到底都是因为和7有关!所以,他现在甚至讨厌一切和7有关的数! 什么样的数和7有关呢? 如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关-- 1.整数中某一位是7: 2.

HDU 4507 吉哥系列故事――恨7不成妻(数位DP+结构体)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4507 题目大意:如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关 1.整数中某一位是7: 2.整数的每一位加起来的和是7的整数倍: 3.这个整数是7的整数倍: 求一定区间内和7无关的数字的平方和. 解题思路:这里我们用一个结构体分别存储符合条件的数的个数n,从当前位开始至末尾的数值s(比如一个数当前为1234***,*表示还不知道的位值,代表的就是***),从当前位开始至末尾的数的平方

hdu 4507 吉哥系列故事――恨7不成妻 数位dp

题意:中文题. 思路:设dp[pos][i][j]表示当前考虑pos位,之前的数位和对7的余数为i,之前的数值对7的余数为j,与之后的(pos+1)位组合满足条件 的状态(包括之后(pos+1)位满足的个数,后缀和sum,后缀平方和),详见代码: /********************************************************* file name: hdu4507.cpp author : kereo create time: 2015年02月10日 星期二

HDU 4507 吉哥系列故事——恨7不成妻

需要推下平方和的式子..维护个数,和,平方和. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define mod 1000000007LL using namespace std; long long bit[30],tab[50],ret=0,t,l,r; struct pnt { long long val1,val2,val3; pnt (long