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} 的一个子集。 在这里,找到以下表达式的最小可能值:

(max⁡i∈SAi)×(∑i∈SBi).(i∈Smax​Ai​)×(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

InputcopyOutputcopy
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();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值