Codeforces Round #299 (Div. 2) C. Tavas and Karafs 二分搜索+数列

C. Tavas and Karafs
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Karafs is some kind of vegetable in shape of an 1 × h rectangle. Tavaspolis people love Karafs and they use Karafs in almost any kind of food. Tavas, himself, is crazy about Karafs.

Each Karafs has a positive integer height. Tavas has an infinite 1-based sequence of Karafses. The height of the i-th Karafs issi = A + (i - 1) × B.

For a given m, let's define an m-bite operation as decreasing the height of at most m distinct not eaten Karafses by 1. Karafs is considered as eaten when its height becomes zero.

Now SaDDas asks you n queries. In each query he gives you numbers lt and m and you should find the largest number r such thatl ≤ r and sequence sl, sl + 1, ..., sr can be eaten by performing m-bite no more than t times or print -1 if there is no such number r.

Input

The first line of input contains three integers AB and n (1 ≤ A, B ≤ 1061 ≤ n ≤ 105).

Next n lines contain information about queries. i-th line contains integers l, t, m (1 ≤ l, t, m ≤ 106) for i-th query.

Output

For each query, print its answer in a single line.

Examples
input
2 1 4
1 5 3
3 3 10
7 10 2
6 4 8
output
4
-1
8
-1
input
1 5 2
1 5 10
2 7 4
output
1
2



Source

Codeforces Round #299 (Div. 2)


My Solution

题意:每个萝卜长度为 hi = a + (i - 1) * b,然后每次询问是每次操作最多把 m 个不同的未吃完的萝卜每个咬掉1单位长度,最多 t 次操作,其中求最大的r,是的[l......r]访问内的萝卜被这 t,m的操作吃完


二分搜索+数列

首先r必须且只要满足2个条件即可,1)a + (r - 1) * b <= t

                                                                2) sum{hi | l <= i <= r } <= t * m

所以对于每个询问进行一次二分搜索即可。

suml = (2 * a + ((l - 1) - 1) * b) * (l - 1) / 2;
LL x = l, y = (t - a) / b + 1 + 1, mid;    // y = (t - a) / b + 1 + 1 多加个1不上整数除法的精度损失, 也可以直接用y = 2e6
while(x + 1 < y){
    mid = (x + y) >> 1;
    if(check(a, b, suml, t, m, mid)) x = mid;
    else y = mid;

}

然后答案可能在x里也可能在y里,且y比x更优,所以

if(check(a, b, suml, t, m, y)) r = y;
else if(check(a, b, suml, t, m, x)) r = x;
else r = -1;

即可

复杂度 O(nlogn)


#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int maxn = 1e6 + 8;

inline bool check(const LL &a, const LL &b, LL &suml, const LL &t, const LL &m, const LL &mid)
{
    if(a + (mid - 1) * b > t) return false;
    if((2*a + (mid - 1) * b) * mid / 2 - suml > t * m) return false;
    else return true;
}

int main()
{
    #ifdef LOCAL
    freopen("c.txt", "r", stdin);
    //freopen("c.out", "w", stdout);
    int T = 2;
    while(T--){
    #endif // LOCAL
    ios::sync_with_stdio(false); cin.tie(0);

    LL a, b, n, l, t, m, r, suml;
    cin >> a >> b >> n;

    while(n--){
        r = -1;
        cin >> l >> t >> m;
        suml = (2 * a + ((l - 1) - 1) * b) * (l - 1) / 2;
        LL x = l, y = (t - a) / b + 1 + 1, mid;    // y = (t - a) / b + 1 + 1 多加个1不上整数除法的精度损失, 也可以直接用y = 2e6
        while(x + 1 < y){
            mid = (x + y) >> 1;
            if(check(a, b, suml, t, m, mid)) x = mid;
            else y = mid;
        }

        //cout << x << " " << y << endl;
        if(check(a, b, suml, t, m, y)) r = y;
        else if(check(a, b, suml, t, m, x)) r = x;
        else r = -1;

        if(n) cout << r << "\n";
        else cout << r << endl;
    }

    #ifdef LOCAL
    cout << endl;
    }
    #endif // LOCAL
    return 0;
}

  Thank you!

                                                                                                                                               ------from ProLights 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值