質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

662閲覧

Pythonで、累算代入文とふつうの代入分とで処理時間が異なるのはなぜですか?(AtCoderの質問)

hacosato

総合スコア48

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

1グッド

1クリップ

投稿2021/07/10 14:27

AtCoder ABC 209のCについてのご質問です。
https://atcoder.jp/contests/abc209/tasks/abc209_c

Python

1n = int(input()) 2c = list(map(int, input().split())) 3c = c.sorted() 4ans = 1 5for i in range(n): 6 ans *= max(c[i]-i, 0) % 1000000007 7print(ans)

というコードを書きましたがTLE(問題で指定された実行時間以内にプログラムが終了しない)になりました。

Python

1n = int(input()) 2c = list(map(int, input().split())) 3c = c.sorted() 4ans = 1 5for i in range(n): 6 ans = ans * max(c[i]-i, 0) % 1000000007 7print(ans)

のように最後から2行目を書き換えると高速に動作し、AC(正答)になりました。

累算代入文とふつうの代入分とのちがいと認識していますが、なぜ処理時間が異なるのでしょうか?

https://docs.python.org/ja/3/reference/simple_stmts.html?highlight=%E4%BB%A3%E5%85%A5#augmented-assignment-statements

ドキュメントのここの部分は関係ありますか?
(読んでみましたがいまひとつよくわかりませんでした…)

Python 3.8.2です。

asari.👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

累算代入文は関係ありません。

Pythonの整数は無限桁が可能ですが、桁数が長くなると掛け算の時間がかかるためです。

以下と見て考えてください。

python

1>>> c = [1000000006, 1000000005] 2>>> ans = 1 3>>> for i in range(len(c)): 4... ans *= max(c[i]-i, 0) % 1000000007 5... 6>>> print(ans) 71000000010000000024

と次は結果が違います。

python

1>>> c = [1000000006, 1000000005] 2>>> ans = 1 3>>> for i in range(len(c)): 4... ans = ans * max(c[i]-i, 0) % 1000000007 5... 6>>> print(ans) 73

最初と同じ結果は以下です。

python

1>>> c = [1000000006, 1000000005] 2>>> ans = 1 3>>> for i in range(len(c)): 4... ans = ans * (max(c[i]-i, 0) % 1000000007) 5... 6>>> print(ans) 71000000010000000024

投稿2021/07/10 14:52

ppaul

総合スコア24666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hacosato

2021/07/18 02:29

確認が大変遅くなり申し訳ありません。 理解しました。 最終行 print(ans) を print(ans % 1000000007) に変えると結果は合うようでしたが、それだとサンプル作っていただいたように、c[i]が1000000007未満である限りansが大きくなり続けてしまいますね…。 わたしが提示した ans *= max(c[i]-i, 0) % 1000000007 だと、かけるほうの数(max(c[i]-i, 0))のみmodをとっていて、かけられる数(=ans)のmodをとれていないのを見落としていました。 今回は乗算のたびにansのmodをとっていきたいので、最初にわたしが提示した通り、forの中を ans = ans * max(c[i]-i, 0) % 1000000007 とする必要がありそうです。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問