問題:AtCoder Beginner Contest 190: D - Staircase Sequences
解説
解説PDFまんまです。
初項a, 末項b とすると、数列は[a, a+1, ... , b-1, b]と表現できる
この数列の総和をSとすると、
今回の問題では より、
両辺2倍すると、
となる。これを満たすの組の個数を求める問題である。
このとき、
とおくと★は、
となる。
はそれぞれ正整数なので、の組はそれぞれの約数といえる。
なのでの約数を列挙して()、の約数について、
が成立する個数を数えたい。
①より より、これを②に代入すると、
式変形すると、
この式を満たすものを数えればよい。
つまり、の個数を数えれば良い。
例として、入力例1のN = 12のときを考える。
数列はそれぞれ
- [12]
- [3,4,5]
- [-2, -1, ... ,4, 5]
- [-11, -10, ..., 11, 12]
になるらしいが、それぞれ①と②にaとbを代入してみると、
- a=12, b=12 ⇒ A=24, B=1
- a=3, b=5 ⇒ A=8, B=3
- a=-2, b=5 ⇒ A=3, B=8
- a=-11, b=12 ⇒ A=1, B=24
となる。
A, Bはそれぞれ2N=24の約数になっていることがわかる。
コーナーケース
- 特になし
実装
# -*- coding:utf-8 -*- def diviser(n): """約数を列挙して返す""" ans = [] i = 1 while True: if i*i > n: break m = n%i if m==0: ans.append(i) if not n//i in ans: ans.append(n//i) i += 1 return ans def solve(): N = int(input()) ans = 0 divs = diviser(2*N) divs.sort() for i in range(len(divs)): A, B = divs[-i-1], divs[i] if B>A: break """ A = a+b B = b-a+1 をそれぞれ満たすか? すなわち式変形して、 B+A-1 = 2bを満たすか? つまりB+A-1は偶数か? """ if (B+A-1)&1==0: ans += 2 print(ans) if __name__ == "__main__": solve()
ソート等含めた計算量はです 。