题意:打印纸张,大于多少份多少钱一张,价格是非递减的,纸张数是增加的。。
怎么想的怎么搞,就是有一个坑点,先二分出这个需求在哪一个纸张区间内,然后直接打印要花多少钱,多打印一些要花多少钱。。。
坑点就在多打印一些,不一定是多打印到需求所在的那个右边界,往右继续走可能花的钱更少(价格降的大),,所以维护一个后缀
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int MAXN=100010;
const ll INF=1000000000000000ll;
int n,m;
struct Node
{
int s,p;
ll sum;
}a[MAXN];
ll sum[MAXN];
int findx(int x)
{
int l=0,r=n-1;
while(l<=r)
{
int mid=(l+r)>>1;
if(x>=a[mid].s)
l=mid+1;
else
r=mid-1;
}
return l-1;
}
int main()
{
int t,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
scanf("%d%d",&a[i].s,&a[i].p);
a[i].sum=(ll)a[i].s*a[i].p;
}
for(i=0;i<n;i++)
sum[i]=INF;
sum[n-1]=a[n-1].sum;
for(i=n-2;i>=0;i--)
{
sum[i]=min(a[i].sum,sum[i+1]);
}
int x;
while(m--)
{
scanf("%d",&x);
int pos=findx(x);
ll temp=(ll)a[pos].p*x;
ll ans=temp;
if(pos<n-1)
ans=min(ans,sum[pos+1]);
printf("%I64d\n",ans);
}
}
return 0;
}