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,如果直接记录下数字, ...
随机推荐
- JS中,如何查询一个对象的所有属性
var res = ""; for(var p in object) { res += p + ","; } alert(res);
- SQL约束脚本的用法
1.主键约束:要对一个列加主键约束的话,这列就必须要满足的条件就是分空因为主键约束:就是对一个列进行了约束,约束为(非空.不重复)以下是代码 要对一个列加主键,列名为id,表名为emp 格式为:a ...
- C++第三课(2013.10.03 )
函数的默认参数: 1.函数的默认参数必须放在形参的右边而且在默认形参的右边不能出现没有无默认参数的形参 2.如果函数的声明给出了默认的参数,那么函数的实现就不能定义默认参 3.声明成员函数时没有给出默 ...
- openpyxl
openpyxl库的使用,这个处理xlsx还是挺有用的 ref:传送门 from openpyxl import Workbook from openpyxl import load_workbook ...
- AFNnetworking快速教程,官方入门教程译
AFNnetworking快速教程,官方入门教程译 分类: IOS2013-12-15 20:29 12489人阅读 评论(5) 收藏 举报 afnetworkingjsonios入门教程快速教程 A ...
- rtf表格的合并
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil Calibri;}{\f1\fnil\fcharset134 \'cb\'ce\ ...
- 转:从BeagleBone谈AM335x硬件系统设计
链接:http://blog.chinaunix.net/uid-730738-id-3266690.html 作者:chenzhufly 从BeagleBone谈AM335x硬件系统设计 日期 ...
- 通过内省机制设置JavaBean
一.步骤: 1)使用PropertyDescriptor类获取属性描述者对象 //pd引用Student的name属性 PropertyDescriptor pd = new PropertyDesc ...
- codeforces Ilya and Matrix
http://codeforces.com/contest/313/problem/C #include <cstdio> #include <cstring> #includ ...
- Qt浅谈之四十五QSplitter实现自由伸缩滑动窗口
一.简介 最近看到一篇Qt实现伸缩滑动的窗口的文章,但其代码不完整.便在此重新书写了完整的代码,并开源出来.窗口的中央有滑动条可以动态改变子窗口的大小,隐藏的按钮可以快速伸缩子窗口.其效果图如下: 二 ...