HDU 4507 有点复杂却不难的数位DP
首先来说,,这题我wrong了好几次,代码力太弱啊。。很多细节没考虑。。
题意:给定两个数 L R,1 <= L <= R <= 10^18 ;求L 到 R 间 与 7 无关的数的平方和
什么数与7 无关?
1 没有数字7
2 不是7的倍数
3 所有数字的和不是7的倍数
我们先来考虑一下 如果这题问的是: L 到 R 间 与7 无关的数有多少个?
这道题该怎么思考? 给一点提示 dp 方程可以写成三维的 num(i,j,k) 其中 i 代表数的位数 j 代表 这个数对7取模的余数 k 代表这个数所有数字和对7取模的值,至于num(i,j,k) 当让就是这种数的个数了, 方程的转化也很简单 从数末尾逐步填数字 l (0~9)的话 num(i+1,(j*10+l)%7,(k+l)%7)+=num(i,j,k);
接下来 我默认你知道 num[i][j][k] 该怎么求了 这个时候 再来考虑一下 L 到 R 间与7 无关的数的和 ? 这个时候不用考虑的太复杂,,因为首先,你在求num[i][j][k]的时候已经求出了所有的满足条件的数的所有可能,要求和,无非就是哪一位的那个数字有多少个。
如果我们的dp是逐步往数的末尾填数 ,这个时候可以这样写 sum(i,j,k)其中i,j,k和num的i,j,k一个意思,然后sum表示满足这种情况的数的和 方程的转换可以写为:同样从数末尾逐步填数字 l (0~9)-- num(i+1,(j*10+l)%7,(k+l)%7)+=sum(i,j,k)*10+num(i,j,k)*l;
再来考虑平方和就比较容易了,,我们知道如果前面的数是a 我们往后面塞一个数字l 那么我们要求的数的平方和是---(10*a+l)^2 也就是100*a*a+20*a*l+l*l
方程我就不写了,,然后接下来的思路都是和上面的类似
贴出渣渣的代码。。。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include <string>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<stdlib.h>
#include <vector>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define ll __int64
#define CL(a,b) memset(a,b,sizeof(a))
#define MAXNODE 100010
ll MOD=; ll s,e; ll dp[][][];
ll wsu[][][];
ll num[][][];
ll val[];
void initval()
{
int i=;
val[]=;
val[]=;
for(i=;i<=;i++)
{
val[i]=val[i-]*;
}
} void initdp()
{
int i,j,k,l;
CL(dp,);
CL(num,);
CL(wsu,);
for(i=;i<;i++)
{
if(i==)continue;
dp[][i%][i%]+=i*i;
wsu[][i%][i%]+=i;
num[][i%][i%]++;
}
num[][][]=;
for(i=;i<;i++)
{
for(j=;j<;j++)
{
for(k=;k<;k++)
{
for(l=;l<;l++)
{
if(l==)continue;
num[i+][(j+l)%][(k*+l)%]+=num[i][j][k]%MOD;
num[i+][(j+l)%][(k*+l)%]%=MOD;
wsu[i+][(j+l)%][(k*+l)%]+=(wsu[i][j][k]*(ll)+(ll)l*(num[i][j][k]))%MOD;
wsu[i+][(j+l)%][(k*+l)%]%=MOD;
dp[i+][(j+l)%][(k*+l)%]+=(((ll)l*(ll)l*num[i][j][k])+dp[i][j][k]*+(ll)*(ll)l*wsu[i][j][k]*(ll))%MOD;
dp[i+][(j+l)%][(k*+l)%]%=MOD;
}
// printf("%d %d %d %I64d\n",i,j,k,dp[i][j][k]);
}
}
}
} ll pro(ll n)
{
if(n==)return ;
ll rem=;
ll nu[];
int w,i,j,k;
nu[]=;
ll tem=n,va;w=,rem=;
while(tem!=)
{
nu[w]=tem%;
tem/=;
w++;
}
va=;
int su=;
ll v=;
while(--w)
{
if(nu[w]==)
{
for(i=;i<w;i++)nu[i]=;
nu[w]=;
}
for(i=nu[w]-;i>=;i--)
{
if(i==)continue;
for(j=;j<;j++)
{
for(k=;k<;k++)
{
if((su+i+j)%==)continue;
if(((ll)v+(ll)i*val[w]+(ll)k)%==)continue;
ll pre=(va+(ll)i*(val[w]%MOD))%MOD;
pre%=MOD;
rem+=(((pre*pre)%MOD)*(num[w-][j][k]%MOD))%MOD;
rem%=MOD;
rem+=dp[w-][j][k]%MOD;;
rem%=MOD;
rem+=((((ll)*pre)%MOD)*wsu[w-][j][k]%MOD)%MOD;
rem%=MOD;
}
}
}
rem%=MOD;
va+=(nu[w]*(val[w]%MOD))%MOD;
va%=MOD;
v+=nu[w]*(val[w]%);
v%=;
su+=nu[w];
su%=;
}
if(v!=&&su!=)rem+=(va*va)%MOD;
return rem%MOD;
} int main()
{
int tt;
initval();
initdp();
scanf("%d",&tt);
while(tt--)
{
scanf("%I64d %I64d",&s,&e);
ll rs=pro(s-1LL);
ll re=pro(e);
ll rem=re-rs;
rem=rem%MOD;
if(rem<)rem+=MOD;
// printf("%I64d %I64d ",rs,re);
printf("%I64d\n",rem);
}
return ;
}
HDU 4507 有点复杂却不难的数位DP的更多相关文章
- 【HDU 5456】 Matches Puzzle Game (数位DP)
Matches Puzzle Game Problem Description As an exciting puzzle game for kids and girlfriends, the Mat ...
- 【HDU 4352】 XHXJ's LIS (数位DP+状态压缩+LIS)
XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU - 4389 X mod f(x)(数位dp)
http://acm.hdu.edu.cn/showproblem.php?pid=4389 题意 为[A,B] 区间内的数能刚好被其位数和整除的数有多少个. 分析 典型的数位dp...比赛时想不出状 ...
- 【HDU】4352 XHXJ's LIS(数位dp+状压)
题目 传送门:QWQ 分析 数位dp 状压一下现在的$ O(nlogn) $的$ LIS $的二分数组 数据小,所以更新时直接暴力不用二分了. 代码 #include <bits/stdc++. ...
- HDU 4389——X mod f(x)(数位DP)
X mod f(x) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Probl ...
- hdu 3709 Balanced Number(平衡数)--数位dp
Balanced Number Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) ...
- hdu 2089 记忆化搜索写法(数位dp)
/* 记忆化搜索,第二维判断是否是6 */ #include<stdio.h> #include<string.h> #define N 9 int dp[N][2],digi ...
- hdu:2089 ( 数位dp入门+模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 数位dp的模板题,统计一个区间内不含62的数字个数和不含4的数字个数,直接拿数位dp的板子敲就行 ...
- 浅谈数位DP
在了解数位dp之前,先来看一个问题: 例1.求a~b中不包含49的数的个数. 0 < a.b < 2*10^9 注意到n的数据范围非常大,暴力求解是不可能的,考虑dp,如果直接记录下数字, ...
随机推荐
- python之6-2高阶函数
1. map函数 map(函数A,字符串或者列表) map函数的意思是将函数A依次作用到字符串的每个字符或者列表的每个元素. 例如: map(lambda x: x*x,[1,2]) [1, 4] 这 ...
- 1. Server.Transfer和Response.Redirect
今天在使用ServerTransfer和Response.Redirect定位到当前页面来实现刷新页面时,发现了一些现象: 1.使用Response.Redirect刷新本页面,造成当前页面显示的数据 ...
- VC中如何获取当前时间(精度达到毫秒级)
标 题: VC中如何获取当前时间(精度达到毫秒级)作 者: 0xFFFFCCCC时 间: 2013-06-24链 接: http://www.cnblogs.com/Y4ng/p/Millisecon ...
- 2016ICPC China-finals 题解
A:ans=n/3,因为8=1(mod7) B: C: D:二分+贪心,二分答案,即个数,check(mid)时贪心看能不能放成mid个; E:贪心,列出不等关系,然后写个高精度分数类; F:二分+h ...
- 较优H圈matlab实现
大家好,我是小鸭酱,博客地址为:http://www.cnblogs.com/xiaoyajiang %解决完备图中的较优H圈 clc clear w = [ inf 6 1 8 3 1 ;... ...
- swift字典集合-备
Swift字典表示一种非常复杂的集合,允许按照某个键来访问元素.字典是由两部分集合构成的,一个是键(key)集合,一个是值(value)集合.键集合是不能有重复元素的,而值集合是可以重复的,键和值是成 ...
- 怪胎:Android开发ImageView图片无法显示
今天碰到一个非常奇怪的问题: 在Android中ImageView无法显示加载的本地SDCard图片. 具体过程是:先调用本地照相机程序摄像,然后将拍摄的图片加载在ImageView中显示. publ ...
- android获取屏幕宽高与获取控件宽高
获取屏幕宽高 // 获取屏幕宽高(方法1) int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); // 屏幕宽(像素 ...
- 【转】Ubuntu命令行下安装、卸载、管理软件包的方法
原文网址:http://oss.org.cn/html/47/n-67447.html 一.Ubuntu中软件安装方法 1.APT方式 (1)普通安装:apt-get install softname ...
- 【转】 ubuntu12.04更新源 官网和163等
原文网址:http://blog.csdn.net/zhangliang_571/article/details/8813999 分类: LINUX 摘要: 本文列出ubuntu 12.04 LTS更 ...