题目链接在这里:Problem - 7106 (hdu.edu.cn)
这题是要求一个函数在一段区间上的极值,这是一个四次函数,通过因式分解并没有什么有价值的发现,但是我们发现,如果固定了一个变量,剩下的就是一个二次函数,显然二次函数求最值还是很好操作的,打表可以发现g(x)的最大值也只有54,所以我们可以枚举g(x)然后二分找极值,将极值和端点值中取一个最小值即可
代码直接贴了队友的(zmhyyds
1 #include<bits/stdc++.h> 2 #include<cstdio> 3 #include<vector> 4 using namespace std; 5 typedef long long LL; 6 const int M=1e6+10;//54 7 int T,g[M]; 8 LL A,B,C,D,N,ANS; 9 vector<int>V[60]; 10 LL calc(LL a){ 11 return A*a*a*g[a]+B*a*a+C*a*g[a]*g[a]+D*a*g[a]; 12 } 13 int main() 14 { 15 freopen("1.in","r",stdin); 16 freopen("1.out","w",stdout); 17 for(int i=1;i<=1e6;i++){ 18 int a=i; 19 while(a){ 20 g[i]+=a%10; 21 a=a/10; 22 } 23 V[g[i]].push_back(i); 24 } 25 for(int i=1;i<=54;i++){ 26 sort(V[i].begin(),V[i].end()); 27 } 28 scanf("%d",&T); 29 while(T--){ 30 scanf("%lld%lld%lld%lld%lld",&A,&B,&C,&D,&N); 31 ANS=min(calc(1ll),calc(N)); 32 for(int i=1;i<=54;i++){ 33 LL lsa=A*i,lsb=B,lsc=C*i*i,lsd=D*i; 34 LL lsx=(-lsc-lsd)/(2*lsa+2*lsb); 35 LL L=0,R=V[i].size()-1;LL l=L,r=R; 36 if(V[i][0]>N) continue; 37 //然后找R; 38 while(l<=r){ 39 int mid=(l+r)>>1; 40 if(V[i][mid]<=N) { 41 R=mid; 42 l=mid+1; 43 } 44 else r=mid-1; 45 } 46 LL ls=-1;l=L,r=R; 47 while(l<=r){ 48 int mid=(l+r)>>1; 49 if(V[i][mid]<=lsx) { 50 ls=mid; 51 l=mid+1; 52 } 53 else r=mid-1; 54 } 55 if(ls!=-1) { 56 ANS=min(ANS,calc(V[i][ls])); 57 } 58 ls=-1;l=L,r=R; 59 while(l<=r){ 60 int mid=(l+r)>>1; 61 if(V[i][mid]>=lsx) { 62 ls=mid; 63 r=mid-1; 64 } 65 else l=mid+1; 66 } 67 if(ls!=-1) { 68 ANS=min(ANS,calc(V[i][ls])); 69 } 70 } 71 printf("%lld\n",ANS); 72 } 73 return 0; 74 }