D - Staircase Sequences Editorial
			
			by  tatyam
 tatyam
			
		
		
		数列 \([A, A + 1, \dots, B - 1, B]\) の総和は、各要素に \([B, B-1, \dots, A + 1, A]\) を足すことを考えると、 \(\dfrac{(A + B)(B - A + 1)}{2}\) です。
よって、この問題は
\[ (A + B)(B - A + 1) = 2N \quad (A ≤ B) \]
の整数解の個数を求める問題に言い換えることができます。
このとき、 \(A + B, B - A + 1\) はどちらも正の整数であるため、どちらも \(2N\) の約数になります。
そこで、 \(2N=x \times y\) と正の整数 \(2\) つに分解する方法を列挙し、
\[ \begin{cases} A + B = x\\ B - A + 1 = y\\ \end{cases} \]
を解いて整数解の個数を数えます。
この解は \(x\) と \(y\) の偶奇が異なるとき、
\(A = (x - y + 1)/2,\ B = (x + y - 1)/2\)
で、 \(x\) と \(y\) の偶奇が同じとき整数解は存在しません。
これより、 \(2N\) を偶奇の異なる正の整数 \(2\) つに分解する方法の数がこの問題の答えになります。
\(2N\) の 約数列挙 は計算量 \(O(\sqrt N)\) でできるため、 \(O(\sqrt N)\) でこの問題を解くことができます。
また、 \(2N\) は \(2\) を素因数に \(1\) つ以上含むため、\(x,y\) のどちらか片方しか \(2\) を素因数に持たないことを考えると、
\(M=\) ( \(N\) を \(2\) で割り切れなくなるまで割った数 ) として、 ( \(M\) の約数の個数 )\({}\times 2\) がこの問題の答えになります。
回答例 (C++)
#include <iostream>
#include <cmath>
using namespace std;
using ll = int64_t;
int main(){
    ll N;
    cin >> N;
    while(N % 2 == 0) N /= 2;
    ll sq = sqrt(N), ans = 0;
    for(ll i = 1; i <= sq; i++) if(N % i == 0) ans += 2;
    if(sq * sq == N) ans--;
    cout << ans * 2 << endl;
}
回答例 (Python)
N = int(input())
while N % 2 == 0:
    N //= 2
sq = int(N ** 0.5)
ans = sum(N % i == 0 for i in range(1, sq + 1)) * 2 - (sq * sq == N)
print(ans * 2)
				posted:
				
				
				last update:
				
			
