列表

详情


NC21665. mathlover和她的粉丝团

描述

lsmathlover所有粉丝团的总团长,已知一共有nmathlover的粉丝团,但是由于地域的差异,导致粉丝团的人数有差异,对于第i个粉丝团有ai个粉丝。mathlover希望所有粉丝团的人数一样,这样就可以雨露均沾,不会偏袒任何粉丝。对于一个粉丝团,增加一个粉丝的代价是当前粉丝团人数除以2,而减少一个粉丝的代价是当前粉丝团人数。你能帮助ls完成这个任务计算出最少需要花费多少使得所有粉丝团人数一样吗?

输入描述

多组输入:

第一行:输入一个n,表示粉丝团的个数(n≤100000)

接下来一行,n个数ai,表示每个粉丝团的人数(1≤ai≤1e6)

输出描述

对于每一行,输出一个数,表示使所有粉丝团人数一样的最小代价

示例1

输入:

4
2 3 4 5

输出:

8

说明:

关于样例:将4个粉丝团的人数都变为4,对于第一个团需要的代价为2/2+3/2=2,对于第二个团需要的代价为3/2,对于三个团需要的代价为0,对于第四个团需要的代价为5,2+1+5=8。而变成其他任何人数,代价都比8大。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 45ms, 内存消耗: 988K, 提交时间: 2020-03-25 17:08:05

#include<bits/stdc++.h>
#define maxn 100010
#define ll unsigned long long
using namespace std;
int a[maxn],n;
ll f[maxn],g[maxn],ans;
ll s1(int x)
{
	return 1LL*x*(x+1)/2;
}
ll s2(int x)
{
	return 2LL*s1(x/2)-(x/2)*(~x&1);
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
		sort(a+1,a+n+1),ans=1ULL<<63,f[0]=g[n+1]=0;
		for(int i=1;i<=n;i++)
		f[i]=f[i-1]+s2(a[i]-1);
		for(int i=n;i;i--)
		g[i]=g[i+1]+s1(a[i]);
		for(int i=1;i<=n;i++)
		ans=min(ans,s2(a[i]-1)*(i-1)-f[i-1]+g[i+1]-s1(a[i])*(n-i));
		printf("%llu\n",ans);
	}
	return 0;
}

C++14(g++5.4) 解法, 执行用时: 130ms, 内存消耗: 4300K, 提交时间: 2020-06-09 08:49:14

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define V 1000000
#define LL long long
using namespace std;
int n,p[V+5];
int main()
{
	RI i,x,t;LL f,g;W(~scanf("%d",&n))
	{
		for(g=i=0;i<=V;++i) p[i]=0;for(i=1;i<=n;++i) scanf("%d",&x),++p[x],g+=1LL*x*(x+1)/2;
		LL ans=1e18;for(f=t=0,i=0;i<=V;++i) f+=1LL*t*((i-1)/2),f+g<ans&&(ans=f+g),t+=p[i],g-=1LL*(n-t)*(i+1);
		printf("%lld\n",ans);
	}return 0;
}

上一题