题解:MX-2025-7S-T1

题面

MX-2025-7S-T1. 最大权值

![[../../题面/MX题面/MX-2025-7S-T1. 最大权值|MX-2025-7S-T1. 最大权值]]

分析

蒟蒻解法

(感觉该思路太想当然,但是题面中没有超乎该思路的特殊情况所以对了)

我们考虑需要用 \([k+1,n]\) 区间的那些元素替换 \([1,k]\) 区间的哪些元素。我们希望用‘价值’尽可能大的元素替换‘价值’尽可能小的元素。

我们定义元素 \(a_i\) 的价值为 \(a_i+(k-i)\times c\) 表示:原始元素大小去掉‘赶路费’。

再将原来 \(k\) 个元素分成两部分,一部分是位置 \([1,k]\) 的元素升序排序为 \(q\) 集,一部分是位置 \([k+1,n]\) 的元素降序排序为 \(p\) 集。

然后将位置 \([k+1,n]\) 价值比位置 \([1,k]\) 价值大的元素交换,答案即为价值差之和加上原 \([1,k]\) 区间元素和

\[ans=\sum_{i=1}^k{a_i}+\sum_{p_j>q_j,1\le j\le k}(p_j-q_j) \]

官方解法

假设我们已经知道最终需要的前 \(k\) 个是哪些元素,我们把它们看作 1,剩下的位置看作 0,我们需要把这些 1 移动到前 \(k\) 个,例如 \(k = 3\),这些元素的位置分别是 4, 7, 9,会发现一共需要 \(4 + 7 + 9 - 1 - 2 - 3\) 次移动。

因此我们把第 \(i\) 个元素看作 \(a_i - i \times c\),取最大的 \(k\) 个,再将答案加上 \(\frac{k \times (k+1) \times c}{2}\) 即可。

代码

蒟蒻代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+1;
typedef long long ll;
ll n,k,c,a[N],ans;
int qidx,pidx,lq,lp;
vector<int>q,p;
int main(){
	scanf("%d%d%d",&n,&k,&c);
	for(int i=1;i<=n;i++){
		scanf("%d",a+i);
		if(i<=k)q.emplace_back(a[i]+(k-i)*c),ans+=a[i];
		else p.emplace_back(a[i]-(i-k)*c);
	}
	sort(q.begin(),q.end(),less<int>());
	sort(p.begin(),p.end(),greater<int>());
	lq=q.size(),lp=p.size();
	while(qidx<lq&&pidx<lp&&p[pidx]>q[qidx])ans+=p[pidx]-q[qidx],qidx++,pidx++;
	cout<<ans;
	return 0;
}

官方代码

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+7,M=22;
long long n,k,c,f[N],ans,sum;
int main() {
    cin>>n>>k>>c;
    for(int i=1;i<=n;i++) cin>>f[i],f[i]-=1ll*i*c;
    sort(f+1,f+n+1); 
    for(int i=1;i<=k;i++) ans+=f[n-i+1]+1ll*i*c;
    return cout<<ans<<endl,0;
}
posted @ 2025-08-20 20:55  badn  阅读(5)  评论(0)    收藏  举报