mayoko’s diary

プロコンとかいろいろ。

Codeforces Round #299 (Div. 2) C. Tavas and Karafs

解法

まずl番目の値がtより大きい場合はどうしようもないので-1を返す。
そうでない時は二分探索する。r番目の数まで0にすることのできる必要十分条件は,s[r] <= tかつsum(s[l], ..., s[r]) <= m*tである。C++の場合オーバーフローに注意(全部10^6で抑えられるのでlong long で足りるが適当にhigh = 10^9とかすると多分死ぬ)。

以下ソースコード

ll A, B, T;

bool ok(int l, int t, int m, ll med) {
    ll L = A+l*B;
    ll R = A+med*B;
    ll num = med-l+1;
    ll sum = (L+R) * num / 2;
    if (sum <= (ll)m * t && R <= t) return true;
    return false;
}

int solve(int l, int t, int m) {
    ll L = A+l*B;
    if (L > t) return -1;
    ll low = l, high = 1e6+7;
    while (high - low > 1) {
        ll med = (high+low) / 2;
        if (ok(l, t, m, med)) {
            low = med;
        } else {
            high = med;
        }
    }
    return low+1;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> A >> B >> T;
    while (T--) {
        int l, t, m;
        cin >> l >> t >> m;
        l--;
        cout << solve(l, t, m) << endl;
    }
    return 0;
}