该题数据量很大, 需要用二分加速算法。
题意比较难懂: 给你一个无穷项等差序列, 有n个查询, 对于每个查询, 有三个数 l, t, m, 每次从第l个数之后的数种选择最多m个数使得他们的值减一, 经过最多t次, 求一个最大的r, 使得从l到r所有数都减为0。
显然这是一个递增序列, 那么我们直接二分答案就行了 。 如果满足这段序列求和 <= t*m 并且 a[r] < t,那么这个答案就是正确的 (YY一下,容易证明)。
另外还学到了一个二分上界的好姿势。
细节参见代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
const int maxn = 100;
ll T,n,m,l,t,A,B;
ll sum(ll mid) {
ll v = A*mid + mid*(mid-1)/2*B;
ll u = A*(l-1) + (l-1)*(l-2)/2*B;
return v - u;
}
int main() {
while(~scanf("%I64d%I64d%I64d",&A,&B,&n)) {
while(n--) {
scanf("%I64d%I64d%I64d",&l,&t,&m);
if(sum(l) > t) { printf("-1\n"); continue; }
ll R = l+t, L = l, mid;
while(R >= L) {
mid = (R+L)/2;
if(sum(mid) <= t*m && A + (mid-1)*B <= t) L = mid + 1;
else R = mid-1;
}
printf("%I64d\n",L-1);
}
}
return 0;
}