分析:
1.由于价格是递减的,所以可能出现si*pi>sj*pj(j>i)。所以要有一个数组来储存当前端点的最小值。
2.然后二分查找当前的si,比较q*p[i]和M[i+1].不过在这之前要确认i是小于n的。】
3.upper_bound是返回第一个大于当前值得坐标,否则返回左闭右开的右端点。而lower_bound是返回第一个大于等于当前值得坐标。所以这里采用upper_bound。
1 #include <iostream> 2 #include <cstdio> 3 #include <math.h> 4 #include <algorithm> 5 using namespace std; 6 #define M 100010 7 #define ll long long 8 ll s[M],p[M],q[M]; 9 ll n,m; 10 ll best[M]; 11 int main() 12 { 13 int T; 14 scanf("%d",&T); 15 for(int i=0;i<T;i++) 16 { 17 18 scanf("%d%d",&n,&m); 19 for(int i=1;i<=n;i++) 20 { 21 scanf("%lld%lld",&s[i],&p[i]); 22 } 23 ll Min = s[n]*p[n]; 24 best[n] = Min; 25 for(int i =n-1;i>=1;i--) 26 { 27 Min = min(Min,s[i]*p[i]); 28 best[i] = Min; 29 } 30 for(int i=1;i<=m;i++) 31 { 32 scanf("%lld",&q[i]); 33 } 34 for(int i=1;i<=m;i++) 35 { 36 if(q[i]>=s[n]) 37 { 38 printf("%lld ",q[i]*p[n]); 39 continue; 40 } 41 int t = upper_bound(s+1,s+1+n,q[i])-s-1; 42 printf("%lld ",min(best[t+1],q[i]*p[t])); 43 } 44 } 45 return 0; 46 }