Codeforces Round #376 (Div. 2) F. Video Cards(前缀和,好题)

来源:互联网 发布:大数据的特点是什么 编辑:程序博客网 时间:2024/05/16 12:55

题意:
给一个n长度的序列,问从序列中找一个数作为第一个数,把不小于它的数变成它或者它的倍数(不是他的倍数时只能减小成为他的倍数),并使得这些数的和最大。


题解:

首先记录每个数出现次数,这个数组处理前缀和,然后对所有数进行排序,从前到后枚举每个数成为第一个数,然后枚举倍数j,找到在这个数j倍-j+1倍的数目,这些数最终都变成了第一个数的j倍,然后求和取最大就可以了。

注意要去重。

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>using namespace std;typedef long long ll;const int MAXN=200000+100;int a[MAXN],pre[MAXN*2];int main(){memset(pre,0,sizeof(pre));int n;scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]),pre[a[i]]++;for(int i=1;i<=MAXN*2;i++) pre[i]=pre[i-1]+pre[i];sort(a+1,a+n+1);int m=unique(a+1,a+n+1)-a-1; ll ans=0;for(int i=1;i<=m;i++){ll tmp=0;for(int j=2;(j-1)*a[i]<=a[m];j++){int p=(j-1)*a[i],q=j*a[i];tmp+=(ll)(pre[q-1]-pre[p-1])*a[i]*(j-1);}ans=max(ans,tmp);}printf("%I64d\n",ans);return 0;}


0 0
原创粉丝点击