Arithmetics Competition(贪心+排序+前缀和)
https://codeforces.com/contest/2132/problem/E
题目大意:给你两堆数字,分别有n,m个,要求第一堆选出不超过X个数,第二堆选出不超过Y个数,总共选出的个数恰好为Z个,求这Z个数和的最大值。
思路:如果对两堆选出的个数不做限制,那么我们只需要选出这两堆数的最大Z个数求和就行了,其中这Z个数中包含Xz个第一堆的数,包含Yz个第二堆的数,题目要求我们第一堆选出的数不能超过X,第二堆不超过Y,Z<=X+Y,所以如果某一堆在Z中的个数超过限制,那么就要增加另一堆选出的数。用前缀和计算出前Z个数中有多少个第一堆的数,然后判断两堆分别取多少个数,输出结果就行了。
Code:
void solve()
{int n,m,q;cin>>n>>m>>q;vector<int> a(n),b(m);vector<PII> v;for(auto &t:a) cin>>t,v.push_back({t,1});for(auto &t:b) cin>>t,v.push_back({t,0});sort(a.rbegin(),a.rend());sort(b.rbegin(),b.rend());sort(v.rbegin(),v.rend());vector<int> sum(m+n+1,0),suma(n+1,0),sumb(m+1,0);sum[0]=v[0].se,suma[0]=a[0],sumb[0]=b[0];for(int i=1;i<m+n;i++){sum[i]=sum[i-1]+v[i].se;if(i<n) suma[i]=suma[i-1]+a[i];if(i<m) sumb[i]=sumb[i-1]+b[i];}while(q--){int x,y,z;cin>>x>>y>>z;int res=0,geta=0,getb=0;if(sum[z-1]>x) geta=x,getb=z-sum[z-1];if(z-sum[z-1]>y) getb=y,geta=z-y;if(sum[z-1]<=x&&z-sum[z-1]<=y) geta=sum[z-1],getb=z-sum[z-1];if(geta) res+=suma[geta-1];if(getb) res+=sumb[getb-1];cout<<res<<endl;}
}