문자열 수를 10진법으로 바꾸는 테크닉2 - n을 n번 이어붙인 정수
n을 n번 이어붙였을때, 그것을 998244353으로 나눈 나머지를 구하는 문제
숫자를 이어붙인 문제는... 한번 10진법으로 바꿔보면 해결법이 보이는 경우가 있다
https://deepdata.tistory.com/1235
12을 12번 이어붙인다면
121212121212121212121212
그러면 12를 12번 이어붙였으니까 1을 12개 붙인 1....1(12번)에 12를 곱하면 되나?
라고 생각했는데 아니더라고
12*10^11 + 12*10^10 + ... + 12랑 같은건가?? 했는데...
실제로 계산기 해보니까 111111111111 * 12 = 1333333333332이기도 하네
그러면 분해를 해보자고
120000000000000000000000
1200000000000000000000
12000000000000000000
120000000000000000
1200000000000000
....
12
첫번째 수는 길이가 2인 12가 11번 붙어있으니까 0이 22개 붙어야겠지
2번째 수는 길이가 2인 12가 10번 붙어있으니까 0이 20개
...
12 * 10^22 + 12 * 10^20 + ... + 12
비슷하게 132를 132번 이어붙인다면??
132132132132....132
얘를 분해한다면??
13200000000....000
...
132
여기서 첫번째 수는? 132에다가 뒤에 길이가 3인 132가 131번 붙었겠지
2번째 수는 132에다가 뒤에 길이가 3인 132가 130번 붙었겠지
...
일반적으로 n을 n번 이어붙인다면??
n의 길이가 d일때 첫번째 수는 n에다가 길이가 d인 n이 n-1번 붙었을거니까
(n-1)d개의 0이 있을거고
2번째 수는 n에다가 길이가 d인 n이 n-2번 붙었을테니까
(n-2)d개의 0이 있을거고
...
$$V_{n} = n*10^{(n-1)d} + n*10^{(n-2)d} + n*10^{(n-3)d} +... + n = n(1 + 10^{d} + 10^{2d} + ... + 10^{(n-1)d})$$
여기서 $1 + 10^{d} + 10^{2d} + ... + 10^{(n-1)d}$는 초항이 1이고 공비가 $10^{d}$이며 항 수가 n개인 등비수열의 합이다.
$$V_{n} = n * \frac{10^{nd} - 1}{10^{d} - 1}$$
$10^{d} - 1$은 998244353과 서로소이므로....
서로소라고 확신할 수 있나??
모르겠으면 n이 최대 10^18이므로 d는 1부터 19까지 가능하다. 이 경우에 대해 998244353과 나눠보면 될 것이다..
아무튼 페르마의 소정리를 이용하여 모듈로 곱셈의 역원을 구하고 10^nd의 경우 pow() 함수로 나머지를 구하면서 빠르게 구하면
n = input()
d = len(n)
n = int(n)
mod = 998244353
a = n % mod
b = pow(10**d-1,mod-2,mod)
c = (pow(10,n*d,mod) - 1) % mod
print((a*b*c) % mod)
'알고리즘 > 애드 혹 알고리즘' 카테고리의 다른 글
논리식의 일부를 바꿔서 원하는 결과가 나오게 만드는 방법 (0) | 2024.09.23 |
---|---|
a b k d e g h i l m n ng o p r s t u w y 순서로 정렬하기? (0) | 2024.09.14 |
맨 위 정수가 주어질때, 아래 두 수의 합이 위 정수가 되는 피라미드 만들기 (0) | 2024.09.06 |
특정한 정점들을 반드시 포함하는 최소 정점 트리 만들기 - list말고 반드시 set을 사용해야하는 경우 (0) | 2024.08.31 |
n개의 구간 각각에서 어떤 정수들을 골라 합해 0을 만들 수 있는가? (0) | 2024.08.24 |