题目链接
题意: 给你正整数a、b,求出s取某个整数时,Ei的最小值。(各参数的范围相当复杂)
解法:已经很明显了,预处理求出所有前i个deg²*freq的和、前i个freq的和。
二分找出最大j的取值t,使得(a*deg[j]²*M),然后答案就能以O(1)立刻求出。
记住不能按推导公式直接求解: 因为b*M*sum_freq[L]超了LTM,只能求代入原公式
求出b*M*(sum_freq[L]-sum_freq[t]).
二分也可用upper_bound()代替。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define llt unsigned long long int
using namespace std;
const int Size=2*1e5+7;
llt d[Size],f[201000],Sd[201000],Sf[201000];
llt M,L;
int binfen(llt x,llt a){
if(a*d[1]>x) return -1;
int l=1,r=L;
while(lint mid=(l+r+1)>>1;
if(a*d[mid]else r=mid-1;
}
return l;
}
int main(){
scanf("%llu%llu",&M,&L);
llt a,b;
Sd[0]=Sf[0]=0;
for(int i=1;i<=L;++i){
scanf("%llu%llu",&a,&f[i]);
d[i]=a*a;
Sd[i]=Sd[i-1]+d[i]*f[i];
Sf[i]=Sf[i-1]+f[i];
}
int Q;
scanf("%d",&Q);
while(Q--){
llt a,b;
scanf("%llu%llu",&a,&b);
//cout<
int t=binfen(b*M,a);
if(t==-1)printf("%llu\n",b*M*(Sf[L]));
else printf("%llu\n",a*(Sd[t])+b*M*(Sf[L]-Sf[t]));
}
return 0;
}