CodeForces 626E Simple Skewness

本文介绍一种算法,通过三分法寻找序列中特定子集,使得该子集中所有数值的平均数减去中位数的值达到最大。讨论了选取奇数个元素的原因,并给出了详细的实现步骤及代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意为给定一个序列,从中选若干个数,使得平均数减去中位数值最大,答案一样输出任意即可。

首先有一个有意思的小结论:选取的数一定为奇数个。

如果暴力的话我们会想到枚举区间长度。简单思考过后我们会发现,如果区间非常短,中位数在平均数中占比太大,使得两数之差很小。如果区间非常长,区间的平均数又会趋近于中位数。这于是满足了三分的条件。我们三分区间一半的长度n,选取最大的n个以及小于中位数最大的n个便是使得平均数最大的那些数了。由于如果使用浮点数会产生精度误差,我们便可以将除法转换为乘法进行运算。我们设三分下来的左边为mid1,右边为mid2,左边求的和为ans1,右边求的和为ans2,则应有(ans1)/(mid1*2+1)-这时的中位数>=(ans2)/(mid2*2+1)+这时的中位数  ,才会将区间的r改为mid2。变形可知如果ans1*(mid2*2+1)>=ans2*(mid1*2+1)) 就会将r改为mid2-1。

下附AC代码。

#include<iostream>
#include<algorithm>
#define maxn 200050
using namespace std;
long long n;
long long num[maxn];
long long cha=-1,pos=0,len=0;
long long sum1[maxn];
long long sum2[maxn];
long long cal(long long x,long long y)
{
	long long sum=0;
	sum+=sum1[y];
	sum-=sum1[y-x-1];
	sum+=sum1[n];
	sum-=sum1[n-x];
	return sum;
}
int main()
{
	cin>>n;
	for(long long i=1;i<=n;i++)
	cin>>num[i];
	if(n==1 || n==2)
	{
		cout<<"1"<<endl;
		cout<<num[1]<<endl;
		return 0;
	}
	
	sort(num+1,num+1+n);
		
	for(long long i=1;i<=n;i++)
	{
		sum1[i]=num[i]+sum1[i-1];
	}
		
	for(long long i=2;i<=n-1;i++)
	{
		long long l=1,r=min(n-i,i-1);
		long long now=0;
		long long cnt=0;
		while(l<r)
		{
			long long mid1=(2*l+r)/3;
			long long mid2=(2*r+l+2)/3;
			
			long long ans1=cal(mid1,i);
			long long ans2=cal(mid2,i);
			
			if(ans1*(mid2*2+1)>=ans2*(mid1*2+1))
			r=mid2-1;
			else
			l=mid1+1;
			
			cnt++;
			if(cnt>123)
			break;
		}
		now=cal(l,i);
		now-=(2*l+1)*num[i];
		if(now-(2*len+1)>cha-(2*l+1))
		{
			cha=now;
			pos=i;
			len=l;
		}
	}
	
	cout<<2*len+1<<endl;
	for(long long i=1;i<=len;i++)
	cout<<num[i]<<" ";
	
	cout<<num[pos];
	
	for(long long i=n-len+1;i<=n;i++)
	cout<<" "<<num[i];
	
	cout<<endl;
}

### Codeforces 887E Problem Solution and Discussion The problem **887E - The Great Game** on Codeforces involves a strategic game between two players who take turns to perform operations under specific rules. To tackle this challenge effectively, understanding both dynamic programming (DP) techniques and bitwise manipulation is crucial. #### Dynamic Programming Approach One effective method to approach this problem utilizes DP with memoization. By defining `dp[i][j]` as the optimal result when starting from state `(i,j)` where `i` represents current position and `j` indicates some status flag related to previous moves: ```cpp #include <bits/stdc++.h> using namespace std; const int MAXN = ...; // Define based on constraints int dp[MAXN][2]; // Function to calculate minimum steps using top-down DP int minSteps(int pos, bool prevMoveType) { if (pos >= N) return 0; if (dp[pos][prevMoveType] != -1) return dp[pos][prevMoveType]; int res = INT_MAX; // Try all possible next positions and update 'res' for (...) { /* Logic here */ } dp[pos][prevMoveType] = res; return res; } ``` This code snippet outlines how one might structure a solution involving recursive calls combined with caching results through an array named `dp`. #### Bitwise Operations Insight Another critical aspect lies within efficiently handling large integers via bitwise operators instead of arithmetic ones whenever applicable. This optimization can significantly reduce computation time especially given tight limits often found in competitive coding challenges like those hosted by platforms such as Codeforces[^1]. For detailed discussions about similar problems or more insights into solving strategies specifically tailored towards contest preparation, visiting forums dedicated to algorithmic contests would be beneficial. Websites associated directly with Codeforces offer rich resources including editorials written after each round which provide comprehensive explanations alongside alternative approaches taken by successful contestants during live events. --related questions-- 1. What are common pitfalls encountered while implementing dynamic programming solutions? 2. How does bit manipulation improve performance in algorithms dealing with integer values? 3. Can you recommend any online communities focused on discussing competitive programming tactics? 4. Are there particular patterns that frequently appear across different levels of difficulty within Codeforces contests?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值