二分 Tavas and Karafs:CodeForces 535C

来源:互联网 发布:怎么看淘宝店铺买家秀 编辑:程序博客网 时间:2024/05/19 14:38

题目:CodeForces 535C

time limit per test2 seconds
memory limit per test256 megabytes
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 is si = 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 l, t and m and you should find the largest number r such that l ≤ 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 A, B and n (1 ≤ A, B ≤ 10^6, 1 ≤ n ≤ 10^5).

Next n lines contain information about queries. i-th line contains integers l, t, m (1 ≤ l, t, m ≤ 10^6) 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

题意:

有个阶梯,第一个台阶的高度为A,其他台阶高度递增B。给出N个询问(l,t,m),你可以进行最多t次操作,每次最多可将m个台阶高度减少1。问从第l个台阶开始操作的话,最多可以使得多少连续(必须以l开头)的台阶高度变成0。

思路

思路题。

首先二分答案,如何判定答案是否可行呢?

要满足两个条件:
①最大值≤t
②sum≤m∗t
这两个条件的必要性是显然的,来证明充分性:
假设m,t能满足的状态叫做(m,t)状态,我们递归的来看。

如果满足上述两个条件的是(m,t)状态,那么我进行一次操作必然会到达(m,t−1)状态,证明分两种情况:
A.当前>0的个数>m,进行一次操作必然满足后者;
可是如果最大值有多个进行1次操作后会不会还有剩余呢?必然不会。因为sum≤m∗t,=t的必然不会超过m个

B.当前>0的个数≤m,进行一次操作必然满足前者;
而此时最大值< t,个数≤m,sum必然小于m∗(t−1)
于是我们一直递归下去,就会到达(m,0)状态,满足上面两个条件这个状态必然是合题意的,递归返回之后就证明了(m,t)状态是合题意的。

代码:

#include <iostream>#include <cstring>#include <cstdio>#include <cstdlib>#include <cmath>#include <algorithm>#define LL long longusing namespace std;int A,B,n,l,T,m;LL x,t;int ok(LL k){    LL la=1LL*(k-1)*B+(LL)x;    if (la>(LL)T) return 0;    if ((la+x)*k/2LL<=t) return 1;    return 0;}int main(){    scanf("%d%d%d",&A,&B,&n);    for (int i=1;i<=n;i++)    {        scanf("%d%d%d",&l,&T,&m);        x=A+1LL*(l-1)*B;        if ((LL)T<x)        {            puts("-1");            continue;        }        t=1LL*T*m;        LL L=1,R=(LL)1e6,ans=0;        while (L<=R)        {            LL M=(L+R)>>1LL;            if (ok(M)) ans=M,L=M+1;            else R=M-1;        }        printf("%d\n",(int)(l-1+ans));    }    return 0;}
原创粉丝点击