//我是来看文章创建时间的= =

膜拜了一下蔡大神。。。。

人生第一道自己写的数位DP。。。好吧以前是看题解然后也不知道为什么就过了的>_< 虽然说现在还是只会裸题= =

数位DP介绍:

http://wenku.baidu.com/link?url=9OS5Ybpw5wx00ahrH8ED2oyIlR1uWwrxT8N4pEg27GgBt2T2hLe4sd_h1rmpY7P0HmeHIEDw9h6_K98dPhhjoMhD2TpKcS8w1X8cC_dkPp_

接下来是bzoj1833题目地址:

http://www.lydsy.com:808/JudgeOnline/problem.php?id=1833

题意挺明显。。

首先我萌可以用F[i,j,k]表示有i位数字且前导为k的数中总共含有多少个数字j(0<=j<=9)。。。

然后蒟蒻不想太麻烦(太弱)。。。干脆把1~9拆成9次一次一次来。。。。

因为题目要求的是[l,r],所以答案就是[0,r]-[0,l-1]......

假设当前求的是0~x的数中含有多少个数字num。。。

首先设x有w位数字,把x拆成w位(第一位为最低位)存在数组h里面,然后处理出x的后i位凑起来是什么数(也就是x的w个后缀)

用pre[i]表示10^(i-1)...10^i-1中含有数字num的个数(这个数对于1~9都是一样的)

那么假设处理到第i(i从最高位(w)开始枚举)位:

1、先考虑之后位上存在num的情况:

当前位取的数字小于h[i]的时候,有h[i]种情况(0~h[i]-1),此时之后的所有数都可以选(之后不管选什么数都不超过x),所以总个数+=h[i]*pre[i-1](当前位每一种情况都能给总个数贡献之后位中数字个数)

当前位取的数字就是h[i]的时候呢?那就华丽地无视掉啦(为什么?想一想。)(后面的位就等到后面再处理了。。)

2、考虑当前位为num的情况:

如果num=h[i],由于之前位上的数字都是上限了,之后的数不能超出x的范围(若之前位数有任意一个小于上限,那么之后的数可以随便选,则已被上面的步骤计算到),所以能贡献出(当前再后一个后缀的值+1)个答案。。。。(因为还有一种情况是后面的全选0)

num>h[i],那么不论之后怎么取,当前这一位都不会额外贡献任何个数。。。(因为想要合法,则前面一定有数小于那一位的上限,贡献在之前就记算了)

num<h[i],那么当取的数字为num的时候后面的数可以随便取,且每种情况都会额外贡献一个个数(也就是当前位上的这个),所以总个数+=10^(i-1)

当然以上是针对数码1~9的情况。。。。如果要求0的个数的话目测比较麻烦。。。当然可以在预处理的时候再开一维pre[i,j]表示i位数字前导为j的个数。。。。。

当然我萌发现,0出现的次数就是所有数字次数总和减去1~9的个数和= =

蒟蒻扯半天最终确定自己语死早了>_<。。。。

下面是更丑的代码TAT

 var
pre,orz,h,sum:array[..]of int64;
ans,ans1:array[..]of int64;
i,j,k,n,m,mid:longint;
l,r,tot,tot1,l1,r1,x,w1,w2:int64;
procedure mahoshojo(x,num,w:int64);
var i:longint;anss:int64;
begin
anss:=;
for i:= to w do h[i]:=x div orz[i-] mod ;
for i:= to w do sum[i]:=x mod orz[i];
for i:=w downto do
begin
inc(anss,pre[i-]*h[i]);
if h[i]>num then inc(anss,orz[i-]);
if h[i]=num then inc(anss,sum[i-]+);
end;
ans[num]:=ans[num]+anss;
tot:=tot-anss;
end;
begin
pre[]:=;
orz[]:=;
for i:= to do orz[i]:=orz[i-]*;
for i:= to do pre[i]:=pre[i-]*+orz[i-];
readln(l,r);
dec(l);
tot:=;
if l> then
begin
l1:=l;
while l1> do begin inc(w1);l1:=l1 div end;
for i:= to w1- do inc(tot,(orz[i]-orz[i-])*i);
if w1> then inc(tot,w1*(l-orz[w1-]+)) else tot:=l+;
end
else
w1:=;
r1:=r;
while r1> do begin inc(w2);r1:=r1 div end;
tot1:=;
for i:= to w2- do inc(tot1,(orz[i]-orz[i-])*i);
if w2> then inc(tot1,w2*(r-orz[w2-]+)) else tot1:=r+;
// writeln(w2,':',tot1,' ',w1,':',tot);
for i:= to do
mahoshojo(l,i,w1);
for i:= to do ans[i]:=-ans[i];
ans[]:=tot;
// writeln(' ',tot);
tot:=tot1;
// writeln('!!!',tot1);
for i:= to do
mahoshojo(r,i,w2);
ans[]:=tot-ans[];
for i:= to do write(ans[i],' ');
writeln(ans[])
end.

话说记得类似的还有一道GDOI的题。。。。要求完全相反= =。。。给你1~某个数字中出现的各个数码的次数,要求判断是否存在这个数。。。

//当然强省数位DP都是T1某弱省就变成了T3(雾。。。或者是T4?。。那年5道题= =)了。。。。。

反正蒟蒻目测只会二分乱搞TAT.。。。。反正怎么玩都不会TLE2333

//四个月没碰键盘TAT。。。脑子还剩一点但是代码能力已经回档到两年前了>_<

//话说考前复习的时候来填坑显然花样作大死。。。YCL:哪有你这样的学生啊!。。。。。。。。

//作死成功。。。

接下来是bzoj3209题目地址:

http://www.lydsy.com:808/JudgeOnline/problem.php?id=3209

这种傻叉题只有我这种蒟蒻第一眼才没看出来= =

就是把1833的加改成了乘。。。。。

预处理出i位数中有j个1的情况总数(其实就是组合数= =组合数好久没打差点不会T_T)。。。。

然后就没什么可扯的了

 var
c:array[..,..]of int64;
i,j,k:longint;
n,m,ans,bilibili,temp:int64;
num:array[..]of int64;
function qpow(a,b:int64):int64;
var date:int64;
begin
date:=;
while b> do
begin
if b and = then date:=date*a mod bilibili;
b:=b shr ;
if b> then a:=a*a mod bilibili
end;
exit(date)
end;
begin
bilibili:=;
readln(n);
m:=trunc(ln(n)/ln())+;
for i:= to m do c[i,]:=;
for j:= to m do
for i:= to m do
c[i,j]:=c[i-,j]+c[i-,j-];
i:=;
while n> do
begin
inc(i);
num[m-i+]:=n and ;
n:=n shr
end;
ans:=;
for i:= to m do
if num[i]= then
begin
for j:= to m-i do
ans:=(ans*qpow(temp+j,c[m-i,j]))mod bilibili;
ans:=ans*(temp+) mod bilibili;
inc(temp)
end;
writeln(ans)
end.

II

数位DP入门:(bzoj1833+3209)的更多相关文章

  1. xbz分组题B 吉利数字 数位dp入门

    B吉利数字时限:1s [题目描述]算卦大湿biboyouyun最近得出一个神奇的结论,如果一个数字,它的各个数位相加能够被10整除,则称它为吉利数.现在叫你计算某个区间内有多少个吉利数字. [输入]第 ...

  2. 数位dp入门 hdu2089 不要62

    数位dp入门 hdu2089 不要62 题意: 给定一个区间[n,m] (0< n ≤ m<1000000),找出不含4和'62'的数的个数 (ps:开始以为直接暴力可以..貌似可以,但是 ...

  3. hdu3555 Bomb 数位DP入门

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 简单的数位DP入门题目 思路和hdu2089基本一样 直接贴代码了,代码里有详细的注释 代码: ...

  4. HDU 2089 不要62【数位DP入门题】

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  5. HDU 2089 不要62(数位dp入门)

    题意:统计区间 [a,b] 中不含 4 和 62 的数字有多少个. 题解:这是数位DP的入门题了,首先要理解数DP的原理,DP[i][j]:代表第i位的第j值,举个栗子:如4715   数位数是从右向 ...

  6. HDU 2089 - 不要62 - [数位DP][入门题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 Time Limit: 1000/1000 MS (Java/Others) Memory Li ...

  7. LightOJ 1140 计数/数位DP 入门

    题意: 给出a,b求区间a,b内写下过多少个零 题解:计数问题一般都会牵扯到数位DP,DP我写的少,这道当作入门了,DFS写法有固定的模板可套用 dp[p][count] 代表在p位 且前面出现过co ...

  8. 【数位dp】bzoj1833: [ZJOI2010]count 数字计数

    数位dp姿势一直很差啊:顺便庆祝一下1A Description 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. Input 输入文件中仅包含一行两个整数a ...

  9. HDU-2089不要62-暴力或数位DP入门

    不要62 题意:给定区间,求在这个区间中有多少个数字,不包含4且不包含62: 这道题作为数位DP的入门题: 暴力也是可以过 #include<cstdio> #include <io ...

随机推荐

  1. iOS 数据加密方案

    iOS安全攻防(二十三):Objective-C代码混淆 提交用户的隐私数据 一定要使用POST请求提交用户的隐私数据GET请求的所有参数都直接暴露在URL中请求的URL一般会记录在服务器的访问日志中 ...

  2. Hive实际应用小结

    1.简介 Hive是数据仓库平台,构建在Hadoop之上用来处理结构化数据.Hive是一个SQL解析引擎,能够将SQL语句转化成MapReduce作业并在Hadoop上执行,从而使得查询和分析更加方便 ...

  3. xcode编译报错unknown error -1=ffffffffffffffff Command /bin/sh failed with exit code 1

    升级完xcode9.1之后,编译项目出现如下错误: CI今日构建时报出如下错误: /Users/xxx/Library/Developer/Xcode/DerivedData/Snowball-ebl ...

  4. MySQL数据库 Event 定时执行任务.

    一.背景 由于项目的业务是不断往前跑的,所以难免数据库的表的量会越来越庞大,不断的挤占硬盘空间.即使再大的空间也支撑不起业务的增长,所以定期删除不必要的数据是很有必要的.在我们项目中由于不清理数据,一 ...

  5. BZOJ4970 IOI2004 empodia障碍段

    4970: [ioi2004]empodia 障碍段 Time Limit: 10 Sec  Memory Limit: 128 MB Description 古数学及哲学家毕氏相信自然之本质为数学. ...

  6. 基于POI和DOM4将Excel(2007)文档写进Xml文件

    刚进公司的training, 下面是要求: Requirements Write a java program to read system.xlsx Use POI API to parse all ...

  7. Q:javax.comm 2.0 windows下Eclipse的配置

    @转自http://blog.csdn.net/zhuanghe_xing/article/details/7523744处 要在Windows下,对计算机的串口或并口等进行编程,可以选择使用Java ...

  8. 一起学Linux04之Linux文件基本属性

    Linux系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限.为了保护系统的安全性,Linux系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定. 为了介绍文件属性,首 ...

  9. 怎么制作html5网站页面让它适应电脑和手机的尺寸

    https://zhidao.baidu.com/question/918130826792192539.html 用以下代码开头:<!DOCTYPE HTML><html>& ...

  10. c=$[$c%5]到let c=$c%5的转换

    刚学shell不知道怎么转换,现在明白了一点点 ,记录下   变成加法就好明白了     c=$[$c+5] let c=$c+5 #变量c等于C加上5后在赋值给自身 let c+=5 #就可以这样表 ...