传送门
题意:
定义第iii个数是a+(i−1)∗ba+(i-1)*ba+(i−1)∗b,先有qqq个询问,每次询问给你l,t,ml,t,ml,t,m代表你可以操作ttt次,每次可以将最多mmm个数减111,每次都需要回答从lll开始, 最远到第几个数,能在执行完这些操作之后[l,r][l,r][l,r]内的数被减成000。
1≤a,b≤1e6,1≤q≤1e5,1≤l,t,m≤1e61\le a,b\le 1e6,1\le q\le 1e5,1\le l,t,m\le 1e61≤a,b≤1e6,1≤q≤1e5,1≤l,t,m≤1e6
思路:
显然可以二分rrr的位置,让后考虑怎么检查答案。
这里有个结论,判断这个区间是否能都被减到000需要满足以下两个条件:
- [l,r][l,r][l,r]内数的和≤t∗m\le t*m≤t∗m
- rrr位置的数需要≤t\le t≤t
第二个显然,第一个背过就行。。
关于第一个的证明,lclclc有一个类似的题,贴个个链接:
链接
这个题的模型就是有mmm个电池,每个电池都有容量cic_ici,有nnn个电脑,每个电脑每分钟都需使用某个电池的一个电量,问能使所有电脑都正常运行的最长时间是多少。
这个题就是二分最长时间,设sum=∑min(ci,mid)sum=\sum min(c_i,mid)sum=∑min(ci,mid),那么电脑能运行midmidmid分钟的充要条件就是mid∗n≤summid*n\le summid∗n≤sum。
#include<bits/stdc++.h>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define Mid (tr[u].l+tr[u].r>>1)
#define pb push_back
using namespace std;const int N=1000010,INF=0x3f3f3f3f,mod=1e9+7;
typedef long long LL;LL a,b,n;LL get(LL l,LL r) {LL n=r-l+1;LL st=a+(l-1)*b;LL ed=a+(r-1)*b;return n*(st+ed)/2;
}void solve() {cin>>a>>b>>n;while(n--) {LL l,t,m;scanf("%lld%lld%lld",&l,&t,&m);LL ls=l,rs=1e9,ans=-1;while(ls<=rs) {LL mid=ls+rs>>1;if(get(l,mid)<=t*m&&a+(mid-1)*b<=t) ans=mid,ls=mid+1;else rs=mid-1;}printf("%lld\n",ans);}
}int main() {int _=1;while(_--) {solve();}return 0;
}