NC20803. [NOI2017]蔬菜
描述
输入描述
第一行包含三个正整数 n, m, k,分别表示蔬菜的种类数目、每天能售出蔬菜总量上
限、小 N 提出的问题的个数。
接下来 n 行,每行输入四个非负整数,描述一种蔬菜的特点,依次为 ai, si, ci, xi ,意义如上文所述。
接下来 k 行,每行输入一个非负整数 pj ,意义如上文所述。
输出描述
输出 k 行,每行包含一个整数,第 i 行的数表示第 i 个问题的答案
示例1
输入:
2 3 2 3 3 3 3 2 5 8 3 1 3
输出:
16 27
说明:
共有两种蔬菜:C++11(clang++ 3.9) 解法, 执行用时: 173ms, 内存消耗: 13268K, 提交时间: 2019-03-16 14:55:02
#include<stdio.h> #include<algorithm> #include<queue> #define ll long long #define N 100005 using namespace std; char buf[1<<20],*p1,*p2; #define GC (p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?0:*p1++) inline void _R(int &x) { char t=GC; while(t<48||t>57)t=GC; for(x=0;t>47&&t<58;t=GC)x=(x<<3)+(x<<1)+t-48; } struct node{int val,id;}; bool operator<(node a,node b){return a.val<b.val;} priority_queue<node>Q; int sum,n,m,q,a[N],s[N],c[N],x[N],fa[N],cnt[N],qry[N],Max; ll ans[N*10]; int GF(int x){return x==fa[x]?x:fa[x]=GF(fa[x]);} int main() { int i;_R(n);_R(m);_R(q); for(i=1;i<=n;i++) { _R(a[i]);_R(s[i]);_R(c[i]);_R(x[i]); Q.push((node){a[i]+s[i],i}); } for(i=1;i<=q;i++) { _R(qry[i]); Max=max(Max,qry[i]); } for(i=1;i<=Max;i++)fa[i]=i,cnt[i]=m; while(Q.size()) { node tmp=Q.top();Q.pop(); int t=x[tmp.id]?(c[tmp.id]-1)/x[tmp.id]+1:Max; if(t>Max)t=Max; t=GF(t);if(!cnt[t])continue; cnt[t]--;sum++;c[tmp.id]--; if(!cnt[t])fa[t]=fa[t-1]; ans[sum]=ans[sum-1]+tmp.val; if(c[tmp.id])Q.push((node){a[tmp.id],tmp.id}); } for(i=1;i<=q;i++)printf("%lld\n",ans[min(sum,qry[i]*m)]); }