【题目描述】
http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf
【题解】
这道题可以从后往前贪心。
若我们知道了第i的答案,我们只要去掉(当前个数-前i-1天能取的个数)个价值最小的蔬菜,就能得到第i-1天的答案。
所以我们现在只要求出最后一天的答案。
把每种蔬菜拆成两份,前c-1个价值为a,最后一个价值为a+s(按变质的顺序)放入优先队列中,依次取出来放入还能放的地方即可。
还能放的地方可以用并查集维护。
复杂度O(n log n)。
/* --------------
user Vanisher
problem bzoj-4946
----------------*/
# include <bits/stdc++.h>
# define ll long long
# define N 1000100
using namespace std;
ll read(){
ll tmp=0, fh=1; char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
return tmp*fh;
}
struct node{
ll num,w,d;
};
bool operator <(node x, node y){
return x.w<y.w;
}
priority_queue <node,vector<node> > hp;
ll n,m,k,p[N],mp[N],mx,f[N],num[N],cnt,ans[N];
ll dad(ll x){
if (x>100000) return dad(100000);
if (f[x]==x) return x;
else return f[x]=dad(f[x]);
}
int main(){
n=read(), m=read(), k=read();
for (ll i=1; i<=n; i++){
ll a=read(), s=read(), c=read(), x=read(),ti;
if (x!=0){
ti=(c-1)/x+1;
hp.push((node){1,s+a,-ti}); hp.push((node){c-1,a,x});
}
else {
hp.push((node){1,s+a,-100000});
hp.push((node){c-1,a,0});
}
}
mx=100000;
for (ll i=1; i<=k; i++) p[i]=read(),mx=max(p[i],mx);
for (ll i=1; i<=mx; i++) f[i]=i, num[i]=m;
while (hp.size()!=0){
node now=hp.top();
hp.pop();
if (now.d<0){
ll p=dad(-now.d);
if (p==0) continue;
num[p]--; mp[++cnt]=now.w;
if (num[p]==0) f[p]=dad(f[p-1]);
ans[mx]=ans[mx]+now.w;
}
else {
ll p,nownum,newp;
if (now.d!=0) p=(now.num-1)/now.d+1,nownum=(now.num-1)%now.d+1;
else p=100000, nownum=now.num;
newp=dad(p), nownum=nownum+(p-newp)*now.d; p=newp;
while (p>0){
if (nownum==0&&now.d==0) break;
ll del=min(num[p],nownum);
for (ll i=1; i<=del; i++) mp[++cnt]=now.w, ans[mx]=ans[mx]+now.w;
nownum=nownum-del; num[p]=num[p]-del;
if (num[p]==0) f[p]=dad(p-1);
newp=dad(f[p-1]);
nownum=nownum+(p-newp)*now.d;
p=newp;
}
}
}
sort(mp+1,mp+cnt+1);
ll tot=mx*m,now=ans[mx],l=1;
for (ll i=mx-1; i>=1; i--){
tot=tot-m;
while (cnt-l+1>tot)
now=now-mp[l++];
ans[i]=now;
}
for (ll i=1; i<=k; i++)
printf("%lld\n",ans[p[i]]);
return 0;
}