AtCoder ABC 133 D - Rain Flows into Dams
irisruneです。弊社でRustが布教されているので試していますが、気を付けなければいけないことが多い言語なのでなかなか大変ですね。
問題
単純な連立方程式を解くだけの問題ですが、規模が大きいので一工夫必要となります。
import sys import numpy as np def input(): return sys.stdin.readline().rstrip() def main(): n = int(input()) a = [int(e) for e in input().split()] x = [0 for _ in range(n)] x[0] = sum(a) - (sum(a[1:n:2]) * 2) for i in range(2, n, 2): x[i] = x[i-2] + ((a[i-1] - a[i-2]) * 2) x[1] = sum(a) - (sum(a[2:n:2]) * 2) for i in range(3, n, 2): x[i] = x[i-2] + ((a[i-1] - a[i-2]) * 2) print(*x) main()
この問題は元連立1次方程式に変換することができます。個の式が作れるため、は計算量で求めることができます。しかし、残りのを同様にして求めると全体の計算量がとなってしまいます。
そこでの関係について考えると、となるため、尺取り法を用いることでを求めることができます。同様にからを求めることができるため、全体の計算量をに抑えることができます。
の偶奇にかかわらず漸化式の形は同じなので、上記提出コードのようにループを2つに分ける意味は処理をわかりやすくする以外に特にありません。
雑記
公式解説を見ればわかる通り、についての漸化式が存在します。というより連立方程式のそれぞれの式が漸化式です。なので尺取り法とか考える必要は全くなかったです。
連立方程式を解けさえすればいいので、ソルバーに突っ込んだりすれば非常に簡単に解けるとは思います。
- ただし、行列の形にすると行列ができてしまうので、疎行列形式でデータを持つ必要があると思います。
- 実はソルバーについて全く詳しくないのですが、疎行列を渡して計算時間がかからないソルバーってざらにあるものなのでしょうか?