<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wcipeg.com/wiki/index.php?action=history&amp;feed=atom&amp;title=Decimal_range_decomposition</id>
		<title>Decimal range decomposition - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://wcipeg.com/wiki/index.php?action=history&amp;feed=atom&amp;title=Decimal_range_decomposition"/>
		<link rel="alternate" type="text/html" href="http://wcipeg.com/wiki/index.php?title=Decimal_range_decomposition&amp;action=history"/>
		<updated>2026-04-24T15:59:55Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.25.2</generator>

	<entry>
		<id>http://wcipeg.com/wiki/index.php?title=Decimal_range_decomposition&amp;diff=1803&amp;oldid=prev</id>
		<title>Dhruvbird at 15:42, 11 August 2014</title>
		<link rel="alternate" type="text/html" href="http://wcipeg.com/wiki/index.php?title=Decimal_range_decomposition&amp;diff=1803&amp;oldid=prev"/>
				<updated>2014-08-11T15:42:56Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;tr style='vertical-align: top;'&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Revision as of 15:42, 11 August 2014&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;L2&quot; &gt;Line 2:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 2:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Informal idea==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Informal idea==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Consider the following problem: given natural number &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, how many of the natural numbers between 1 and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, inclusive, have a &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(&lt;/del&gt;non-&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;strictly) descending &lt;/del&gt;sequence of digits? That is, each digit is less than or equal to the digit on its left, if any. For example, 100 and 321 qualify, but 101 and 123 do not. Assume that the [[naive algorithm]] is not efficient enough as &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; can have up to, say, 15 digits, so performing &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; loop iterations is out of the question.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Consider the following problem: given natural number &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, how many of the natural numbers between 1 and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, inclusive, have a non-&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;ascending &lt;/ins&gt;sequence of digits? That is, each digit is less than or equal to the digit on its left, if any. For example, 100 and 321 qualify, but 101 and 123 do not. Assume that the [[naive algorithm]] is not efficient enough as &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; can have up to, say, 15 digits, so performing &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; loop iterations is out of the question.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;It is hard to find an explicit formula for this quantity, but notice that there are some ranges of natural numbers for which we ''can'' write down a closed form. For example, if the range, instead of being from 1 to &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, were to be from 35000 to 35999, we know at a glance that the answer is 0, since any number starting with the prefix &amp;quot;35&amp;quot; does not have a descending digit sequence. If instead the range were 53000 to 53999, the question becomes: in how many ways can we fill in the digits &amp;lt;math&amp;gt;xyz&amp;lt;/math&amp;gt; so that &amp;lt;math&amp;gt;53xyz&amp;lt;/math&amp;gt; has a descending digit sequence? Well, clearly, each of the digits &amp;lt;math&amp;gt;xyz&amp;lt;/math&amp;gt; can only be 0, 1, 2, or 3. How many ways are there to fill in three slots, each with one of four possible digits, so that the resulting sequence is descending? This can easily be calculated as the binomial coefficient &amp;lt;math&amp;gt;\binom{3 + 4 - 1}{4 - 1} = 20&amp;lt;/math&amp;gt;.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;It is hard to find an explicit formula for this quantity, but notice that there are some ranges of natural numbers for which we ''can'' write down a closed form. For example, if the range, instead of being from 1 to &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, were to be from 35000 to 35999, we know at a glance that the answer is 0, since any number starting with the prefix &amp;quot;35&amp;quot; does not have a descending digit sequence. If instead the range were 53000 to 53999, the question becomes: in how many ways can we fill in the digits &amp;lt;math&amp;gt;xyz&amp;lt;/math&amp;gt; so that &amp;lt;math&amp;gt;53xyz&amp;lt;/math&amp;gt; has a descending digit sequence? Well, clearly, each of the digits &amp;lt;math&amp;gt;xyz&amp;lt;/math&amp;gt; can only be 0, 1, 2, or 3. How many ways are there to fill in three slots, each with one of four possible digits, so that the resulting sequence is descending? This can easily be calculated as the binomial coefficient &amp;lt;math&amp;gt;\binom{3 + 4 - 1}{4 - 1} = 20&amp;lt;/math&amp;gt;.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Dhruvbird</name></author>	</entry>

	<entry>
		<id>http://wcipeg.com/wiki/index.php?title=Decimal_range_decomposition&amp;diff=1801&amp;oldid=prev</id>
		<title>Brian: Created page with &quot;Decimal range decomposition is a standard technique used to simplify problems that involve the digits of ranges (''i.e'', intervals) of natural numbers.&lt;ref&gt;Although this tec...&quot;</title>
		<link rel="alternate" type="text/html" href="http://wcipeg.com/wiki/index.php?title=Decimal_range_decomposition&amp;diff=1801&amp;oldid=prev"/>
				<updated>2014-08-10T20:13:24Z</updated>
		
		<summary type="html">&lt;p&gt;Created page with &amp;quot;&lt;a href=&quot;/wiki/Decimal_range_decomposition&quot; title=&quot;Decimal range decomposition&quot;&gt;Decimal range decomposition&lt;/a&gt; is a standard technique used to simplify problems that involve the digits of ranges (&amp;#039;&amp;#039;i.e&amp;#039;&amp;#039;, intervals) of natural numbers.&amp;lt;ref&amp;gt;Although this tec...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;[[Decimal range decomposition]] is a standard technique used to simplify problems that involve the digits of ranges (''i.e'', intervals) of natural numbers.&amp;lt;ref&amp;gt;Although this technique is standard, it is unclear whether it has a common name. The name &amp;quot;decimal range decomposition&amp;quot; was coined by an author of this article.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Informal idea==&lt;br /&gt;
Consider the following problem: given natural number &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, how many of the natural numbers between 1 and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, inclusive, have a (non-strictly) descending sequence of digits? That is, each digit is less than or equal to the digit on its left, if any. For example, 100 and 321 qualify, but 101 and 123 do not. Assume that the [[naive algorithm]] is not efficient enough as &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; can have up to, say, 15 digits, so performing &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; loop iterations is out of the question.&lt;br /&gt;
&lt;br /&gt;
It is hard to find an explicit formula for this quantity, but notice that there are some ranges of natural numbers for which we ''can'' write down a closed form. For example, if the range, instead of being from 1 to &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, were to be from 35000 to 35999, we know at a glance that the answer is 0, since any number starting with the prefix &amp;quot;35&amp;quot; does not have a descending digit sequence. If instead the range were 53000 to 53999, the question becomes: in how many ways can we fill in the digits &amp;lt;math&amp;gt;xyz&amp;lt;/math&amp;gt; so that &amp;lt;math&amp;gt;53xyz&amp;lt;/math&amp;gt; has a descending digit sequence? Well, clearly, each of the digits &amp;lt;math&amp;gt;xyz&amp;lt;/math&amp;gt; can only be 0, 1, 2, or 3. How many ways are there to fill in three slots, each with one of four possible digits, so that the resulting sequence is descending? This can easily be calculated as the binomial coefficient &amp;lt;math&amp;gt;\binom{3 + 4 - 1}{4 - 1} = 20&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
So it is easy to see that if we are given a range of the form &amp;lt;math&amp;gt;[p \times 10^n, (p+1) \times 10^n)&amp;lt;/math&amp;gt; with &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; nonzero (which we'll call an '''elementary range'''), then the number of integers in this range with descending digits is either zero if the prefix &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; itself does not have descending digits, or else &amp;lt;math&amp;gt;\binom{n + p_0}{p_0}&amp;lt;/math&amp;gt; where &amp;lt;math&amp;gt;p_0&amp;lt;/math&amp;gt; is the last digit of the prefix &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;. For example, the range 53000 to 53999 (inclusive) is represented by &amp;lt;math&amp;gt;p = 53, n = 3&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If the actual range given is from 1 to &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then we can try to '''decompose''' this range into elementary ranges, compute the number of integers with descending digits in ''each'' elementary range as a simple binomial coefficient, and then sum the counts obtained in order to get the final answer. For example, if &amp;lt;math&amp;gt;N = 165&amp;lt;/math&amp;gt;, then we can decompose the range [1, 123] as the ''disjoint union'' of the following ranges: [1, 2), [2, 3), [3, 4), [4, 5), [5, 6), [6, 7), [7, 8), [8, 9), [9, 10), [10, 20), [20, 30), [30, 40), [40, 50), [50, 60), [60, 70), [70, 80), [80, 90), [90, 100), [100, 110), [110, 120), [120, 130), [130, 140), [140, 150), [150, 160), [160, 161), [161, 162), [162, 163), [163, 164), [164, 165), [165, 166). Note that each range is elementary: each range corresponds to the entire set of natural numbers corresponding to some fixed prefix with some fixed number of arbitrary digits following.&lt;br /&gt;
&lt;br /&gt;
==Formal definition==&lt;br /&gt;
The decimal range decomposition of the interval of natural numbers &amp;lt;math&amp;gt;[1, N)&amp;lt;/math&amp;gt; is the disjoint union&lt;br /&gt;
:&amp;lt;math&amp;gt;[1, N) = \bigsqcup_i E(p_i, n_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
where &amp;lt;math&amp;gt;E(p_i, n_i)&amp;lt;/math&amp;gt; denotes an elementary interval, with &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; is a positive integer&amp;lt;ref&amp;gt;Zero is disallowed in order to ensure that all the numbers in each elementary range have the same number of digits, and no number is treated as having leading zeroes.&amp;lt;/ref&amp;gt; and &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; a nonnegative integer:&lt;br /&gt;
:&amp;lt;math&amp;gt;E(p_i, n_i) = [p_i \times 10^{n_i}, (p_i+1) \times 10^{n_i})&amp;lt;/math&amp;gt;&lt;br /&gt;
and the set of elementary intervals used is as small as possible.&lt;br /&gt;
&lt;br /&gt;
==Algorithm==&lt;br /&gt;
To obtain the decimal range decomposition of &amp;lt;math&amp;gt;[1, N)&amp;lt;/math&amp;gt;, there are two stages. In the first stage, we count all integers that have fewer digits than &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;. That is, we decompose the range &amp;lt;math&amp;gt;[1, 10^n)&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; is the largest possible integer such that this range is contained within &amp;lt;math&amp;gt;[1, N)&amp;lt;/math&amp;gt;. That is, &amp;lt;math&amp;gt;n = \lfloor \log_{10} N \rfloor&amp;lt;/math&amp;gt;. In the second stage, we count up to &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; by advancing the leftmost digit, then the next-to-leftmost, and so on, &amp;quot;honing in&amp;quot; on the digit sequence of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===First stage===&lt;br /&gt;
Compute &amp;lt;math&amp;gt;n = \lfloor \log_{10} N \rfloor&amp;lt;/math&amp;gt;. Then decompose the range &amp;lt;math&amp;gt;[1, 10^n)&amp;lt;/math&amp;gt; as&lt;br /&gt;
:&amp;lt;math&amp;gt;[1, 10^n) = \bigsqcup_{i=0}^{n-1} \bigsqcup_{j=1}^9 E(j, i)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Second stage===&lt;br /&gt;
It remains to decompose the range &amp;lt;math&amp;gt;[10^n, N)&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; has the same number of digits as &amp;lt;math&amp;gt;10^n&amp;lt;/math&amp;gt;. Let the digit sequence of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; be denoted &amp;lt;math&amp;gt;\langle d_n d_{n-1} \ldots d_1 d_0 \rangle&amp;lt;/math&amp;gt;. Then&lt;br /&gt;
:&amp;lt;math&amp;gt;[10^n, N) = \bigsqcup_{i=0}^n \bigsqcup_{j=0}^{d_i-1} E(\langle d_n d_{n-1} \ldots d_{i+1} j\rangle, i)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Implementation (C++)===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;lt;utility&amp;gt;&lt;br /&gt;
std::vector&amp;lt;std::pair&amp;lt;long long, int&amp;gt;&amp;gt; drd(long long N) {&lt;br /&gt;
    std::vector&amp;lt;std::pair&amp;lt;long long, int&amp;gt;&amp;gt; res;&lt;br /&gt;
    int exponent = 0;&lt;br /&gt;
    long long pwr = 1;&lt;br /&gt;
    // stage 1&lt;br /&gt;
    while (N/pwr &amp;gt;= 10ll) {&lt;br /&gt;
        for (int d = 1; d &amp;lt;= 9; d++) {&lt;br /&gt;
            res.push_back({d, exponent});&lt;br /&gt;
        }&lt;br /&gt;
        pwr *= 10; exponent++;&lt;br /&gt;
    }&lt;br /&gt;
    // stage 2&lt;br /&gt;
    long long l = pwr;&lt;br /&gt;
    long long p = 1;&lt;br /&gt;
    while (l &amp;lt; N) {&lt;br /&gt;
        if (l + pwr &amp;lt;= N) {&lt;br /&gt;
            res.push_back({p, exponent});&lt;br /&gt;
            l += pwr;&lt;br /&gt;
            p++;&lt;br /&gt;
        } else {&lt;br /&gt;
            pwr /= 10; --exponent;&lt;br /&gt;
            p *= 10;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return res;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Arbitrary ranges==&lt;br /&gt;
Thus, if we know how to compute &amp;lt;math&amp;gt;\sum_{x \in I} f(x)&amp;lt;/math&amp;gt; efficiently for any elementary interval &amp;lt;math&amp;gt;I&amp;lt;/math&amp;gt;, we can compute &amp;lt;math&amp;gt;\sum_{x=1}^{N-1} f(x)&amp;lt;/math&amp;gt; efficiently using the decimal range decomposition. If we are given an arbitrary interval &amp;lt;math&amp;gt;[A, B]&amp;lt;/math&amp;gt; instead for &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to range over, then we just use the fact that&lt;br /&gt;
:&amp;lt;math&amp;gt;\sum_{x=A}^B f(x) = \sum_{x=1}^{B} f(x) - \sum_{x=1}^{A-1} f(x)&amp;lt;/math&amp;gt;&lt;br /&gt;
and use decimal range decomposition on &amp;lt;math&amp;gt;[1, B+1)&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;[1, A)&amp;lt;/math&amp;gt; separately.&lt;br /&gt;
&lt;br /&gt;
==External links==&lt;br /&gt;
* {{Problem|mmm14d|Kuuhaku Numbers}}&lt;br /&gt;
* {{SPOJ|KPSUM|The Sum @ SPOJ}}&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brian</name></author>	</entry>

	</feed>