メメメモモ

プログラミング、筋トレ、ゲーム、etc

C - ±1 Operation 1

atcoder.jp

茶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の差分を計算して、小さい方を解とする。