整体思路:对于每一位,先将当前未达到$limit$部分的段 [如 $0$ ~ $10000$] 直接处理好,到下一位时再处理达到$limit$的部分。

· $1 × 10 ^ n$以内每个数(包括$0$)的出现次数的计算 [即已知$bitnum[n - 1]$,求$bitnum[n]$]: 将$bitnum[n - 1]$乘以$10$,代表$n - 1$处最为每个小段在$n$处出现$10$次,再加上$power10[n - 1]$,即加上新增的最高位该数出现次数。

· $1 × 10 ^ n$以内$0$的出现次数的计算 [即已知$bitzero[n - 1]$,求$bitzero[n]$]: 将$bitzero[n - 1] + power10[n - 2] - 1$ ··· ①,表示在$n - 1$的所有数($power10[n - 2] - 1$)个前都加上一个前导零,再将① $* 10$,表示该小段出现$10$次。

· 处理$limit$位: 首先保存前$n + 1$位的$limit$位,那么前$n + 1$位的$limit$为在当前第$n$位的贡献即它们在$0$ ~ $limit × 10 ^ n$中每一大段停留的次数,即 [它们的出现次数 × $power10[n - 1]$]。

· 处理非$limit$位: 直接加上$bitnum$或$bitzero$(前导零情况)即可。

· 代码:

 #include <iostream>
#include <cstdio>
#include <cstring> using namespace std; typedef long long LL; const int MAXN = + ;
const int MAXM = ; LL power10[MAXN]; LL bitnum[MAXN];
LL bitzero[MAXN]; void Preparation () {
power10[] = ;
for (int i = ; i <= MAXM; i ++)
power10[i] = power10[i - ] * ; bitnum[] = ;
for (int i = ; i <= MAXM; i ++)
bitnum[i] = bitnum[i - ] * + power10[i - ]; bitzero[] = , bitzero[] = ;
for (int i = ; i <= MAXM; i ++)
bitzero[i] = (bitzero[i - ] + power10[i - ] - ) * ;
} LL Answers[][MAXM]; int L, R; int bit[MAXN];
int N; int cobit[MAXN]; void separ (int p) {
memset (cobit, , sizeof (cobit)); if (! p)
cobit[] = ;
while (p) {
cobit[p % ] ++; p /= ;
}
} void Solve (int M, int type) {
if (M <= ) {
if (M == )
Answers[type][] = ; return ;
} int tmpM = M; N = ;
while (tmpM) {
bit[++ N] = tmpM % ; tmpM /= ;
} int bits = ; for (int i = N; i >= ; i --) {
bits *= ; for (int j = ; j < bit[i]; j ++) {
if (bits + j || i == ) { // 处理limit位
separ (bits + j); for (int k = ; k <= ; k ++)
Answers[type][k] += (LL) cobit[k] * power10[i - ];
} for (int k = ; k <= ; k ++)
Answers[type][k] += bitnum[i - ];
Answers[type][] += (bits + j ? bitnum[i - ] : bitzero[i - ]);
} bits += bit[i];
} separ (M); for (int k = ; k <= ; k ++)
Answers[type][k] += cobit[k];
} int main () {
Preparation (); while (~ scanf ("%d%d", & L, & R) && L + R) {
if (L > R)
swap (L, R); memset (Answers, , sizeof (Answers)); Solve (L - , );
Solve (R, ); for (int i = ; i <= ; i ++) {
if (i)
putchar (' '); printf ("%lld", Answers[][i] - Answers[][i]);
} puts ("");
} return ;
} /*
1 10
44 497
346 542
1199 1748
1496 1403
1004 503
1714 190
1317 854
1976 494
1001 1960
0 0
*/

POJ - Problem 2282 - The Counting Problem的更多相关文章

  1. [POJ 2282] The Counting Problem

    [题目链接] http://poj.org/problem?id=2282 [算法] 数位DP [代码] #include <algorithm> #include <bitset& ...

  2. (Problem 73)Counting fractions in a range

    Consider the fraction, n/d, where n and d are positive integers. If nd and HCF(n,d)=1, it is called ...

  3. (Problem 72)Counting fractions

    Consider the fraction, n/d, where n and d are positive integers. If nd and HCF(n,d)=1, it is called ...

  4. UVA 1640 The Counting Problem UVA1640 求[a,b]或者[b,a]区间内0~9在里面各个数的数位上出现的总次数。

    /** 题目:UVA 1640 The Counting Problem UVA1640 链接:https://vjudge.net/problem/UVA-1640 题意:求[a,b]或者[b,a] ...

  5. foj Problem 2282 Wand

     Problem 2282 Wand Accept: 432    Submit: 1537Time Limit: 1000 mSec    Memory Limit : 262144 KB Prob ...

  6. 尺取法 POJ 3320 Jessica's Reading Problem

    题目传送门 /* 尺取法:先求出不同知识点的总个数tot,然后以获得知识点的个数作为界限, 更新最小值 */ #include <cstdio> #include <cmath> ...

  7. POJ 3100 Root of the Problem || 1004 Financial Management 洪水!!!

    水两发去建模,晚饭吃跟没吃似的,吃完没感觉啊. ---------------------------分割线"水过....."--------------------------- ...

  8. 『The Counting Problem 数位dp』

    The Counting Problem Description 求 [L,R]内每个数码出现的次数. Input Format 若干行,一行两个正整数 L 和 R. 最后一行 L=R=0,表示输入结 ...

  9. POJ2282 The Counting Problem

    题意 Language:DefaultEspañol The Counting Problem Time Limit: 3000MS Memory Limit: 65536K Total Submis ...

随机推荐

  1. Hadoop基于Protocol Buffer的RPC实现代码分析-Server端--转载

    原文地址:http://yanbohappy.sinaapp.com/?p=110 最新版本的Hadoop代码中已经默认了Protocol buffer(以下简称PB,http://code.goog ...

  2. bzoj1272 Gate Of Babylon(计数方法+Lucas定理+乘法逆元)

    Description Input Output Sample Input 2 1 10 13 3 Sample Output 12 Source 看到t很小,想到用容斥原理,推一下发现n种数中选m个 ...

  3. bzoj1318[spoj 744] Longest Permutation

    题意 给出一个长度为n的,所有元素大小在[1,n]的整数数列,要求选出一个尽量长的区间使得区间内所有元素组成一个1到区间长度k的排列,输出k的最大值 n<=1e5 分析 不会做,好菜啊.jpg ...

  4. bzoj4815[CQOI2017]小Q的格子

    题意 不简述题意了,简述题意之后这道题就做出来了.放个原题面. 小Q是个程序员. 作为一个年轻的程序员,小Q总是被老C欺负,老C经常把一些麻烦的任务交给小Q来处理. 每当小Q不知道如何解决时,就只好向 ...

  5. MySQL配置文件简单解析

    [mysqld] basedir = /data/mysql datadir = /data/mysqldata tmpdir = /data/mysqltmpdata //mysql的查询临时目录, ...

  6. Spring切面二使用注解

    package com.IC; public interface PhoneBiz { public void buyPhone(int num); //购买手机; public void saleP ...

  7. [Oracle整理]ORA-12705(字符集问题)

    [Oracle整理]ORA-12705(字符集问题)   2017年5月11日 18:11 [Oracle整理]ORA-12705(字符集问题) 说明:本内容是工作用到的知识点整理,来自工作中和网络. ...

  8. mysql数据库----下载安装、操作

    一.mysql概述 1.什么是数据库 ? 答:数据的仓库,如:在ATM的示例中我们创建了一个 db 目录,称其为数据库 2.什么是 MySQL.Oracle.SQLite.Access.MS SQL ...

  9. jsp 的 4 种基本语法

    1.JSP 注释 2.JSP 声明 3.JSP 表达式 4.JSP 脚本 JSP 注释: 注释格式: <%-- 注释内容 --%> 需要注意的是,JSP 的注释不会输出到 HTML 中. ...

  10. TCP/IP地址格式转换API

    1.htonl ()和ntohl( )  ntohl( )-----网络顺序转换成主机顺序(长整型) u_long PASCAL FAR ntohl (u_long netlong); htonl ( ...