A. 打印收费

CZYZ校园内有一家打印店,收费有着奇葩的规则,对于打印的量不同的情况会收取不同的费用。例如打印少于100张的时候,收取20分每张,但是打印不少于100张,收取10分每张,显然打印99张时候应该打印100张,而不是打印99张。现在告诉你打印店的收费策略,给出一些询问,求出打印若干张时候最少需要支付的钱数。

Input

输入数据包含三行,第一行包含两个数nm,表示打印策略的种类有n种,询问有m个;
接下来一行有2n个整数,即S1,P1,S2,P2,,Sn,Pn表示当打印数量不少于Si时,每张收取Pi分。
第三行包含m个整数Q1,Q2,Q3,,Qm,表示询问打印Qi张时,最少花多少钱(分)。

Output

对于每个询问,输出一行一个整数,表示最少花多少分钱打印Qi张。

Samples

Input Copy
2 3
0 20 100 10
0 99 100
Output
0
1000
1000

Hint

  • 对30%的数据满足:0<n,m1e30=S1<S2<<Sn1e51e5P1P2Pn00Qi1e5
  • 对100%的数据满足:0<n,m1e50=S1<S2<<Sn1e9, 1e9P1P2Pn00,0Qi1e9

Source

石光中学 2018泉州集训提高组day7

这个题只要时设置一个z[i]数组时指的时i到n中的最小的权值,

for(int i=n-1;i>=1;i--){
    z[i]=min(z[i+1],z[i]);
}

这样时n*lg(n)的复杂的

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=5e5+100; 
ll s[maxn],p[maxn];
ll z[maxn];
template <typename Tp>
void read(Tp &x){
    x=0;char ch=1;int fh;
    while(ch!='-'&&(ch>'9'||ch<'0')){
        ch=getchar();
    }
    if(ch=='-'){
        fh=-1;ch=getchar();
    }else fh=1;
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+ch-'0';ch=getchar();
    }
    x*=fh;
}
inline char read1()
{
    register char ch=getchar();
    while(ch<'A'||ch>'M')ch=getchar();
    return ch;
}
int n,m;
void inint(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        scanf("%lld%lld",&s[i],&p[i]);    
    }
    for(int i=1;i<=n;i++){
        z[i]=1ll*s[i]*p[i];
    }
    for(int i=n-1;i>=1;i--){
        z[i]=min(z[i+1],z[i]);
    }
}
int main(){
    inint();
    for(int i=1;i<=m;i++){
        ll x;
        scanf("%lld",&x);int k=lower_bound(s+1,s+n+1,x)-s;
        ll ans=x*p[k-1];
        if(k>n){
            printf("%lld\n",ans);
        }
        else{
            printf("%lld\n",min(ans,z[k]));
        }
    }
}

 

posted @ 2021-01-21 00:31  lipu123  阅读(123)  评论(0编辑  收藏  举报