【Codeforces Round #299 (Div. 2) C】 Tavas and Karafs
【链接】 我是链接,点我呀:)
【题意】
【题解】
如果l..r里面的最大值大于t了;则无解最大值小于等于t的话.
每次可以取m个。
然后可以取t次。
也就是说
这一段里面的和<=m*t;
只要A+(i-1)*B大于1e6了就停下来
最坏情况就是A和B都为1
写个rmq+二分就好
【代码】
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e6+10;
ll a[N+100],pre[N+100];
ll A,B,Q;
int n;
const int MAXL = 20;//log2��������
const int INF = 0x3f3f3f3f;//��ֵ����ֵ�����ֵ
struct abc{
ll pre2[MAXL+5],need[N+10];
ll fmax[N+10][MAXL+5];
void init(int n)
{
pre2[0] = 1;
for (int i = 1;i <= MAXL;i++)
{
pre2[i] = pre2[i-1]<<1;
}
need[1] = 0; need[2] = 1;
int temp = 2;
for (int i = 3; i <= n; i++)//need[i]��ʾ����Ϊi��2�Ķ��ٴη�,�������Ϊ[log2i]
if (pre2[temp] == i)
need[i] = need[i - 1] + 1, temp++;
else
need[i] = need[i - 1];
}
void getst(ll *a,int n)
{
for (int i = 1;i <= n;i++)//�±��0��ʼ�ijɶ�Ӧ�ľͺ�
fmax[i][0] = a[i];
for (int l = 1;pre2[l]<=n;l++)
for (int i = 1;i <= n;i++){
if (i+pre2[l]-1<=n)
fmax[i][l] = max(fmax[i][l-1],fmax[i+pre2[l-1]][l-1]);
}
}
int getmax(int l,int r)
{
int len = need[r-l+1];
return max(fmax[l][len],fmax[r-pre2[len]+1][len]);
}
}ST;
bool ok(int l,int r,ll t,ll m){
if (r > n) return false;
int ma = ST.getmax(l,r);
if (ma>t) return false;
ll ju = t*m;
ll sum = pre[r]-pre[l-1];
if (sum <= ju){
return true;
}
return false;
}
int main(){
#ifdef LOCAL_DEFINE
freopen("rush_in.txt", "rt", stdin);
#endif
scanf("%lld%lld%lld",&A,&B,&Q);
for (int i = 1; ;i++){
a[i] = A + (i-1)*B;
if (a[i]>(int)1e6){
n = i-1;
break;
}
}
ST.init(n);
ST.getst(a,n);
for (int i = 1;i <= n;i++){
pre[i] = pre[i-1] + a[i];
}
while (Q--){
int l;
ll t,m;
scanf("%d%lld%lld",&l,&t,&m);
if (l > n){
puts("-1");
continue;
}
int L = l,R = N+10,temp = -1;
while (L<=R){
int mid = (L+R)>>1;
if (ok(l,mid,t,m)){
temp = mid;
L = mid+1;
} else{
R = mid-1;
}
}
printf("%d\n",temp);
}
return 0;
}