A. 打印收费
CZYZ校园内有一家打印店,收费有着奇葩的规则,对于打印的量不同的情况会收取不同的费用。例如打印少于100张的时候,收取20分每张,但是打印不少于100张,收取10分每张,显然打印99张时候应该打印100张,而不是打印99张。现在告诉你打印店的收费策略,给出一些询问,求出打印若干张时候最少需要支付的钱数。
Input
输入数据包含三行,第一行包含两个数n和m,表示打印策略的种类有n种,询问有m个;
接下来一行有2n个整数,即S1,P1,S2,P2,…,Sn,Pn表示当打印数量不少于Si时,每张收取Pi分。
第三行包含m个整数Q1,Q2,Q3,…,Qm,表示询问打印Qi张时,最少花多少钱(分)。
Output
对于每个询问,输出一行一个整数,表示最少花多少分钱打印Qi张。
Samples
Hint
- 对30%的数据满足:0<n,m≤1e3,0=S1<S2<…<Sn≤1e5, 1e5≥P1≥P2≥…≥Pn≥0,0≤Qi≤1e5;
- 对100%的数据满足:0<n,m≤1e5,0=S1<S2<…<Sn≤1e9, 1e9≥P1≥P2≥⋯≥Pn≥00,0≤Qi≤1e9。
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])); } } }