@@ -84,32 +84,223 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3800-3899/3855.Su
8484
8585<!-- solution:start -->
8686
87- ### 方法一
87+ ### 方法一:数学 + 快速幂
88+
89+ 我们从低位到高位枚举每一位数字 $x$,假设当前为第 $i$ 位($i$ 从 $0$ 开始),相当于填了一个数字 $x \cdot 10^i$,其余的 $k - 1$ 位数字,每一位都有 $r - l + 1$ 个选择,所以当前位的贡献为 $x \cdot 10^i \cdot (r - l + 1)^{k - 1}$。对于 $x$ 的选择范围是 $[ l, r] $,所以 $x$ 的总和为 $\frac{(l + r) \cdot (r - l + 1)}{2}$,因此所有数字的总和为:
90+
91+ $$
92+ \begin{aligned}
93+ &\sum_{i = 0}^{k - 1} \frac{(l + r) \cdot (r - l + 1)}{2} \cdot (r - l + 1)^{k - 1} \cdot 10^i \\
94+ = &\frac{(l + r) \cdot (r - l + 1)}{2} \cdot (r - l + 1)^{k - 1} \cdot \frac{10^k - 1}{9}
95+ \end{aligned}
96+ $$
97+
98+ 由于 $k$ 的范围是 $[ 1, 10^9] $,我们需要使用快速幂来计算 $(r - l + 1)^{k - 1}$ 和 $10^k$,另外除法需要使用费马小定理来计算 $9$ 的逆元。
99+
100+ 时间复杂度 $O(\log k)$,空间复杂度 $O(1)$。
88101
89102<!-- tabs:start -->
90103
91104#### Python3
92105
93106``` python
107+ class Solution :
108+ def sumOfNumbers (self , l : int , r : int , k : int ) -> int :
109+ mod = 10 ** 9 + 7
110+
111+ n = r - l + 1
112+
113+ # ((l + r) * (r - l + 1) // 2) % mod
114+ total = (l + r) * n // 2 % mod
94115
116+ # pow(r - l + 1, k - 1, mod)
117+ part1 = pow (n % mod, k - 1 , mod)
118+
119+ # (pow(10, k, mod) - 1)
120+ part2 = (pow (10 , k, mod) - 1 ) % mod
121+
122+ # Fermat inverse of 9
123+ inv9 = pow (9 , mod - 2 , mod)
124+
125+ ans = total
126+ ans = ans * part1 % mod
127+ ans = ans * part2 % mod
128+ ans = ans * inv9 % mod
129+
130+ return ans
95131```
96132
97133#### Java
98134
99135``` java
100-
136+ class Solution {
137+ public int sumOfNumbers (int l , int r , int k ) {
138+ final int mod = 1_000_000_007 ;
139+
140+ long n = r - l + 1L ;
141+
142+ // ((l + r) * (r - l + 1) // 2) % mod
143+ long sum = (long ) (l + r) * n / 2 % mod;
144+
145+ // pow(r - l + 1, k - 1, mod)
146+ long part1 = qpow(n % mod, k - 1 , mod);
147+
148+ // (pow(10, k, mod) - 1)
149+ long part2 = (qpow(10 , k, mod) - 1 + mod) % mod;
150+
151+ // pow(9, mod - 2, mod) (Fermat inverse of 9)
152+ long inv9 = qpow(9 , mod - 2 , mod);
153+
154+ long ans = sum;
155+ ans = ans * part1 % mod;
156+ ans = ans * part2 % mod;
157+ ans = ans * inv9 % mod;
158+
159+ return (int ) ans;
160+ }
161+
162+ private int qpow (long a , int n , int mod ) {
163+ long ans = 1 ;
164+ a %= mod;
165+ for (; n > 0 ; n >> = 1 ) {
166+ if ((n & 1 ) == 1 ) {
167+ ans = ans * a % mod;
168+ }
169+ a = a * a % mod;
170+ }
171+ return (int ) ans;
172+ }
173+ }
101174```
102175
103176#### C++
104177
105178``` cpp
106-
179+ class Solution {
180+ public:
181+ int sumOfNumbers(int l, int r, int k) {
182+ const int mod = 1'000'000'007;
183+
184+ long long n = 1LL * r - l + 1;
185+
186+ // ((l + r) * (r - l + 1) / 2) % mod
187+ long long sum = 1LL * (l + r) * n / 2 % mod;
188+
189+ // pow(r - l + 1, k - 1, mod)
190+ long long part1 = qpow(n % mod, k - 1, mod);
191+
192+ // (pow(10, k, mod) - 1)
193+ long long part2 = (qpow(10, k, mod) - 1 + mod) % mod;
194+
195+ // Fermat inverse of 9
196+ long long inv9 = qpow(9, mod - 2, mod);
197+
198+ long long ans = sum;
199+ ans = ans * part1 % mod;
200+ ans = ans * part2 % mod;
201+ ans = ans * inv9 % mod;
202+
203+ return (int) ans;
204+ }
205+
206+ private:
207+ long long qpow (long long a, long long n, int mod) {
208+ long long ans = 1;
209+ a %= mod;
210+ while (n > 0) {
211+ if (n & 1) {
212+ ans = ans * a % mod;
213+ }
214+ a = a * a % mod;
215+ n >>= 1;
216+ }
217+ return ans;
218+ }
219+ };
107220```
108221
109222#### Go
110223
111224```go
225+ func sumOfNumbers(l int, r int, k int) int {
226+ const mod int64 = 1_000_000_007
227+
228+ n := int64(r - l + 1)
229+
230+ // ((l + r) * (r - l + 1) / 2) % mod
231+ sum := int64(l+r) * n / 2 % mod
232+
233+ // pow(r - l + 1, k - 1, mod)
234+ part1 := qpow(n%mod, int64(k-1), mod)
235+
236+ // (pow(10, k, mod) - 1)
237+ part2 := (qpow(10, int64(k), mod) - 1 + mod) % mod
238+
239+ // Fermat inverse of 9
240+ inv9 := qpow(9, mod-2, mod)
241+
242+ ans := sum
243+ ans = ans * part1 % mod
244+ ans = ans * part2 % mod
245+ ans = ans * inv9 % mod
246+
247+ return int(ans)
248+ }
249+
250+ func qpow(a int64, n int64, mod int64) int64 {
251+ a %= mod
252+ var ans int64 = 1
253+ for n > 0 {
254+ if n&1 == 1 {
255+ ans = ans * a % mod
256+ }
257+ a = a * a % mod
258+ n >>= 1
259+ }
260+ return ans
261+ }
262+ ```
263+
264+ #### TypeScript
265+
266+ ``` ts
267+ function sumOfNumbers(l : number , r : number , k : number ): number {
268+ const mod = 1_000_000_007n ;
269+
270+ const n = BigInt (r - l + 1 );
271+
272+ // ((l + r) * (r - l + 1) / 2) % mod
273+ const sum = ((BigInt (l + r ) * n ) / 2n ) % mod ;
274+
275+ // pow(r - l + 1, k - 1, mod)
276+ const part1 = qpow (n % mod , BigInt (k - 1 ), mod );
277+
278+ // (pow(10, k, mod) - 1)
279+ const part2 = (qpow (10n , BigInt (k ), mod ) - 1n + mod ) % mod ;
280+
281+ // Fermat inverse of 9
282+ const inv9 = qpow (9n , mod - 2n , mod );
283+
284+ let ans = sum ;
285+ ans = (ans * part1 ) % mod ;
286+ ans = (ans * part2 ) % mod ;
287+ ans = (ans * inv9 ) % mod ;
288+
289+ return Number (ans );
290+ }
112291
292+ function qpow(a : bigint , n : bigint , mod : bigint ): bigint {
293+ a %= mod ;
294+ let ans = 1n ;
295+ while (n > 0n ) {
296+ if ((n & 1n ) === 1n ) {
297+ ans = (ans * a ) % mod ;
298+ }
299+ a = (a * a ) % mod ;
300+ n >>= 1n ;
301+ }
302+ return ans ;
303+ }
113304```
114305
115306<!-- tabs:end -->
0 commit comments