茶diffらしいが、実感としては緑diffくらいに感じる。 値の範囲にマイナスが含まれているので、場合分けや反転させる処理が思いつけなかった。 値の範囲が正のみ(D>0 && A,X > 0)であれば、特に難しいことはない。 負の場合(D<0)、反転するには、初項を(A+(N-1)D)の値にして、D=-1 すれば良い。
if (D<0) { A = A + (N-1) * D; D *= -1; }
あとはXに近い項を求める。求め方としては2通り。
項を二分探索するのであれば、0からN-1の範囲で行う。
ll l=0, r=N-1; while (abs(l-r)>1) { ll mid = (l+r)/2; ll a = A + mid * D; if (a <= X) { l = mid; } else { r = mid; } }
(X-A)/Dの計算で項を求めるのであれば、負になる場合とNになる場合も考慮が必要。
ll n = (X-A)/D; if (n < 0) { cout << abs(A-X) << endl; return; } else if (n > N) { cout << abs(A+(N-1)*D-X) << endl; return; }
Xに近い項をiとすると、i か i+1 のそれぞれとXの差分を計算して、小さい方を解とする。