单身! 
依然单身! 
吉哥依然单身! 
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的整数倍;

现在问题来了:吉哥想知道在一定区间内和7无关的数字的平方和。 
Input
输入数据的第一行是case数T(1 <= T <= 50),然后接下来的T行表示T个case;每个case在一行内包含两个正整数L, R(1 <= L <= R <= 10^18)。 
Output
请计算L,RL,R中和7无关的数字的平方和,并将结果对10^9 + 7 求模后输出。
Sample Input
3
1 9
10 11
17 17
Sample Output
236
221
0
Hint

题意:中文好不好。。。

之前做的都是统计满足那些性质的数的 count,这次直接蹦到统计 square sum 了。。。

而这里需要修改的也就是一个返回值问题,不过还是需要基础知识的。

现在看一个例子:4123 ,我现在pos定在1这一位上,也就是需要求出pos位以1开头的满足条件的平方,于是我们发现121 122这两个数都是满足条件的(当然 还有其他满足条件的),怎么算当前为所在的base=100,所以121^2+122^2   =   (100+21)^2+(100+22)^2

= (100^2 + 21^2+2*100*21)   +   (100^2 + 21^2+2*100*21)     =  (100^2*2) + (2*100*(21+22) ) + (21^2+22^2),如此变化需要的是什么,也就是count(符合条件的 个数,相当于100^2*2中的*count)、sum(相当于上面的21+22)、square sum(相当于上面的21^2+22^2),如此拆解就看见分别求之后再合并了,很多题都需要这么拆解的,都忘了ORZ。。。

所以综上,就是在数位dp的基础上修改返回值,并更新就好了!!!

总结:其实数位DP还算是有模板的,能修改的地方无非是返回值(如本例)、dfs中的中间部分、还有dp状态的确定(很重要!!!)


建议做这道题之前先把here这道题A掉,思路会大增,知识修改返回值好了!!!

#include <bits/stdc++.h>
using namespace std;typedef long long LL;
typedef pair<int,pair<LL,LL> > PILL;  /// count满足条件的个数  sum满足条件的和   square sum 满足条件的平方#define F first
#define S second
#define MP make_pairconst int mod = 1e9 + 7;int digit[20];LL pow10[20]; ///打表求pow,这里不适合用pow函数,因为有取余PILL dp[20][7][7][2]; ///pos当前位 和对7取余 remain对7取余 是否包含7
bool vis[20][7][7][2];PILL dfs(int pos,int bitsum,int remain,bool contain,bool flag)
{if(!pos)if(!contain && bitsum && remain)return MP(1,MP(0LL,0LL));elsereturn MP(0,MP(0LL,0LL));if(!flag && vis[pos][bitsum][remain][contain])return dp[pos][bitsum][remain][contain];PILL ret = MP(0,MP(0,0));int end = flag ? digit[pos] : 9;for(int i=0;i<=end;i++){PILL nxt = dfs(pos-1,(bitsum + i) % 7,(remain * 10 + i) % 7,contain | (i == 7),flag && i == end);LL pref = i * pow10[pos-1] % mod;ret.F = (ret.F + nxt.F) % mod;ret.S.F = (ret.S.F + nxt.S.F + pref * nxt.F) % mod;ret.S.S = (ret.S.S + nxt.S.S + pref * pref % mod * nxt.F + 2 * pref * nxt.S.F) % mod;}         if(!flag){vis[pos][bitsum][remain][contain] = true;dp[pos][bitsum][remain][contain] = ret;}return ret;
}long long f(long long n)
{int pos = 0;while(n){digit[++pos] = n % 10;n /= 10;}return dfs(pos,0,0,0,true).S.S;
}int main()
{pow10[0] = 1;for(int i=1;i<20;i++)pow10[i] = pow10[i-1] * 10 % mod;int T;scanf("%d",&T);while(T--){long long a,b;scanf("%I64d%I64d",&a,&b);printf("%I64d\n",(f(b) - f(a-1) + mod) % mod);}return 0;
}

这个用了三维的DP,也就是说出现了包含7的这种不符合条件的情况就直接contiue了,不过在处理有些问题上这种方法不推荐,比如here这种两个条件需要同时满足的,就不好处理了!!!不过下面的这个结构体值得借鉴,因为上面的代码里面的pair虽然写起来很简单,但是可读性还是相对较差的。

/**  如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关——1、整数中某一位是7;2、整数的每一位加起来的和是7的整数倍;3、这个整数是7的整数倍;求一个区间中与7无关的数的平方和*/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const long long MOD=1000000007LL;
struct Node
{long long cnt;//与7无关的数的个数long long sum;//与7无关的数的和long long sqsum;//平方和
}dp[20][10][10];//分别是处理的数位、数字和%7,数%7
int bit[20];
long long p[20];//p[i]=10^iNode dfs(int pos,int pre1,int pre2,bool flag)
{if(pos==-1){Node tmp;tmp.cnt=(pre1!=0 && pre2!=0);tmp.sum=tmp.sqsum=0;return tmp;}if(!flag && dp[pos][pre1][pre2].cnt!=-1)return dp[pos][pre1][pre2];int end=flag?bit[pos]:9;Node ans;Node tmp;ans.cnt=ans.sqsum=ans.sum=0;for(int i=0;i<=end;i++){if(i==7)continue;tmp=dfs(pos-1,(pre1+i)%7,(pre2*10+i)%7,flag&&i==end);ans.cnt+=tmp.cnt;ans.cnt%=MOD;ans.sum+=(tmp.sum+ ((p[pos]*i)%MOD)*tmp.cnt%MOD )%MOD;ans.sum%=MOD;ans.sqsum+=(tmp.sqsum + ( (2*p[pos]*i)%MOD )*tmp.sum)%MOD;ans.sqsum%=MOD;ans.sqsum+=( (tmp.cnt*p[pos])%MOD*p[pos]%MOD*i*i%MOD );ans.sqsum%=MOD;}if(!flag)dp[pos][pre1][pre2]=ans;return ans;
}
long long calc(long long n)
{int pos=0;while(n){bit[pos++]=n%10;n/=10;}return dfs(pos-1,0,0,1).sqsum;
}
int main()
{//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);int T;long long l,r;p[0]=1;for(int i=1;i<20;i++)p[i]=(p[i-1]*10)%MOD;for(int i=0;i<20;i++)for(int j=0;j<10;j++)for(int k=0;k<10;k++)dp[i][j][k].cnt=-1;scanf("%d",&T);while(T--){scanf("%I64d%I64d",&l,&r);long long ans=calc(r);ans-=calc(l-1);ans=(ans%MOD+MOD)%MOD;printf("%I64d\n",ans);}return 0;
}

HDU 4507 吉哥系列故事――恨7不成妻 (平方拆解 + *数位DP 总结)相关推荐

  1. HDU 4507 吉哥系列故事――恨7不成妻 数位DP

    吉哥系列故事--恨7不成妻 Time Limit: 1000/500 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

  2. HDU 4507 吉哥系列故事——恨7不成妻 详解(变态数位DP)

    Problem Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: ...

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

    Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: 2+1+4=7 ...

  4. HDU - 4507 吉哥系列故事——恨7不成妻(数位dp)

    题目链接:点击查看 题目大意:给出闭区间[l,r],求出区间内与7不沾边的数的平方和 与7有关的条件: 整数中某一位是7: 整数的每一位加起来的和是7的整数倍: 这个整数是7的整数倍: 题目分析:抛去 ...

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

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove Tencent马拉松初赛第二场的鬼畜题... 其实 ...

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

    J - 吉哥系列故事――恨7不成妻 HDU - 4507 题解:数位dp 和简单的数位dp不同,这道题要算所有合法数的平方和 考虑到一个数可以写成X=ΣAi*Pi,(其中Ai为X每一位的值,Pi=10 ...

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

    吉哥系列故事--恨7不成妻 ∑i=1n(pre+suc)2∑i=1npre2+suc2+2×pre×sucn×pre2+∑suc2+2×pre∑suc\sum_{i = 1} ^{n}(pre + s ...

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

    单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: 2+1+4=7 7+7=72 77=71 ...

  9. hdu4507吉哥系列故事——恨7不成妻 (数位dp)

    Problem Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: ...

最新文章

  1. mkdir函数linux,linux--access函数与mkdir函数
  2. 【Python3之异常处理】
  3. 关于面试,我也有说的
  4. 2018年 第09届 蓝桥杯 Java B组 决赛真题详解及小结
  5. redis生产环境持久化_在SageMaker上安装持久性Julia环境
  6. python多线程编程(6): 队列同步
  7. Flask爱家租房--房屋管理(获取房东发布的房源信息条目)
  8. Java word 内容读取
  9. 转载:jQuery 1.3.3 新功能
  10. python oop_python中oop
  11. C语言 - 直接插入排序、希尔排序、直接选择排序、堆排序、冒泡排序、快速排序、归并排序、基数排序。
  12. 【概率论与数理统计】1.1 随机事件及其运算
  13. abaqus中的e11 e22_abaqus帮助文档翻译 2.1.11 一摞积木在通用接触下的倒塌分析...
  14. Ubuntu安装蓝牙驱动
  15. android适配器
  16. (转)Java面试笔试题大汇总(最全+详细答案)
  17. 头条视频30万次播放有多少收益,今日头条一个视频收益持续多久
  18. Ubuntu系统中使用todesk设备ID不显示问题解决
  19. 客户成功团队的 OKR 案例
  20. 给我五分钟,带你彻底掌握 MyBatis 缓存的工作原理

热门文章

  1. 英语单词常用词根(五)
  2. Topaz Photo AI V1.1.4 Windows 图片降噪工具
  3. 一行命令堆出你的新垣结衣(已开源),有点牛!
  4. Java下载海康历史视频并合并转码
  5. 国外优秀软件测试网站介绍及测试资料
  6. C语言同学录(通讯录)的实现
  7. 单行文本垂直居中和多行文本垂直居中以及font字体
  8. html语言语法骨架格式,0002 认识HTML(骨架、DOCTYPE、lang、charset)
  9. (3)登录界面———注册界面
  10. 服务器操作系统安装命令,安装windows server 2008r2服务器操作系统