Max × Sum:(枚举,大根堆,滑动窗口)
问题陈述
给定长度为 NN 的序列: A=(A1,A2,…,AN)A=(A1,A2,…,AN) 和 B=(B1,B2,…,BN)B=(B1,B2,…,BN)。
设 SS 为大小为 KK 的 {1,2,…,N}{1,2,…,N} 的一个子集。 在这里,找到以下表达式的最小可能值:
(maxi∈SAi)×(∑i∈SBi).(i∈SmaxAi)×(i∈S∑Bi).
给定 TT 个测试用例;解决每一个。
约束条件
- 1≤T≤2×1051≤T≤2×105
- 1≤K≤N≤2×1051≤K≤N≤2×105
- 1≤Ai,Bi≤1061≤Ai,Bi≤106
- 所有测试用例中 NN 的总和最多为 2×1052×105。
- 所有输入值均为整数。
输入
输入通过标准输入以以下格式给出。这里,caseicasei 表示第 ii 个测试用例。
TT case1case1 case2case2 ⋮⋮ caseTcaseT
每个测试用例的格式如下:
NN KK A1A1 A2A2 …… ANAN B1B1 B2B2 …… BNBN
输出
打印 TT 行。第 ii 行应包含第 ii 个测试用例的答案。
示例 1
Inputcopy | Outputcopy |
---|---|
3 3 2 3 7 6 9 2 4 5 3 6 4 1 5 9 8 6 5 1 7 10 6 61 95 61 57 69 49 46 47 14 43 39 79 48 92 90 76 30 16 30 94 | 42 60 14579 |
在第一个测试用例中,对于 S={2,3}S={2,3},表达式的值为 7×(2+4)=427×(2+4)=42,这是最小值。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
struct ty {
int a,b;
}s[N];
int n,k;
bool cmp(ty a,ty b){
return a.a<b.a;
}
void solved(){
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>s[i].a;
for(int i=1;i<=n;i++) cin>>s[i].b;
sort(s+1,s+1+n,cmp);
priority_queue<int> q;
int sum=0,ans=0x3f3f3f3f3f3f3f3f;
for(int i=1;i<=n;i++){
if(i<=k){
sum+=s[i].b;
q.push(s[i].b);
}
else{
if(q.top()>s[i].b){
sum-=q.top();
sum+=s[i].b;
q.pop();
q.push(s[i].b);
}
}
if(i>=k) ans=min(sum*s[i].a,ans);
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int t=1;
cin>>t;
while(t--){
solved();
}
}