[ABC224] F - Problem where +s Separate Digits

[Q] https://atcoder.jp/contests/abc224/tasks/abc224_f

考察さえできればあっという間でした。

12345 があったとして、
1) +1、 +10、+100、+1000、+10000の回数を考察する。
2) +2、+20、+200、+2000の回数を考察する。
3) +3、+30、+300 の回数を考察する。
...

すると、
1) 1, 11, 112, 1124, 11248
2) 0, 2, 22, 224, 2248
3) 0, 0, 4, 44, 448
なる数列を得られる。法則が見えてきそう。

Q. 12345 として
・1 だけ見る( 10000 が与えられた場合と同じ想定 )
 
DP[見てる桁数][10^x] = 何通りの取り方があるか

      1 2 3 4 5 // 桁数
10^0  1 1 2 4 8 // 1
10^1    1 1 2 4 // 10
10^2      1 1 2 // 100
10^3        1 1 // 1000
10^4          1 // 10000

各桁の総和をとる。
base[] = {1, 11, 112, 1124, 11248 ,,,}

これ、どんな増え方?
0*10 + 2^0 = 1
1*10 + 2^0 = 11
11*10 + 2^1 = 112
112*10 + 2^2 = 1124
...
base[i+1] = base[i] * 10 + 2^i で求まりそう。

・2 だけ見る ( 02000 が与えられた場合と同じ想定)
      1 2 3 4 5 // 桁数
10^0    2 2 4 8
10^1      2 2 4
10^2        2 2
10^3          2
10^4 

base2[] = {0, 2, 22, 224, 2248}

これは、さっきの base からindexを1つずらして2倍したものっぽい。
base2[i] = base[i-1] * 23 だけみる ( 00300 が与えられた場合と同じ想定)
      1 2 3 4 5 // 桁数
10^0      4 4 8
10^1        4 4
10^2          4
10^3          
10^4 

base3[] = {0, 0, 4, 44, 448}
これは、base から index - 2 して 4倍 したものっぽい。

base3[i] = base[i-2] * 2^2


1. base[]を求める。
2. 桁がずれたら、base[N-i] * 2^i でbase数を求める。
3. S の値をかけてあげればよさそう

1:11248
2:4496
3:1344
4:352
5:80

A. 17520

実装

string S;
ll N;
mint base[200010];
mint powtwo[200010];

int main(){
 cincout();
 
 cin >> S;
 N = S.size();
 
 base[0] = 1;
 powtwo[0] = 1;
 rep(i, N-1) powtwo[i+1] = powtwo[i] * 2;
 rep(i, N-1){
   base[i+1] = base[i] * 10 + powtwo[max(0LL, i)];
 }
 mint ans = 0;
 rep(i, N){
   mint n = S[i] - '0';
   ans += base[N-1-i] * powtwo[i] * n;
 }
 cout << ans << endl;
}

https://atcoder.jp/contests/abc224/submissions/26818585


この記事が気に入ったらサポートをしてみませんか?