Codeforces 731 F. Video Cards (prefix and)


Codeforces 731 F. Video Cards
title gist: Given a set of numbers, choose one number as the lead, require all other numbers to be reduced to their multiples, and then sum. Ask for the maximum value of the sum.
Idea: Count the number of occurrences of each number, and then make a prefix sum for quick summation later. Sort the original array to remove duplicates, enumerate each number as a lead, and reduce the remaining numbers and then sum the result. It is sufficient to maintain the maximum value continuously.
PS: A convenient function unique() is used here to remove duplicates. Before use, you need to sort the array. The parameters are the first address and the address after the end of the array, and the new address after the end is returned. (The function does not delete duplicate elements, but just puts them after the tail address.) You can use len=unique(a,a+n)-a to get the length of the array after deduplication.
Attached code:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
int a[maxn];
int cnt[maxn*2+5];
int main()
{
    int n,i,j;
    cin>>n;
    for (i=0;i<n;++i)
    {
        scanf("%d",&a[i]);
        cnt[a[i]]++;
    }
    for (i=1;i<maxn*2;++i)
    {
        cnt[i]+=cnt[i-1];
    }
    sort(a,a+n);
    int len=unique(a,a+n)-a; //去重
    ll ans=0; 
    for (i=0;i<len;++i)
    {
        ll sum=0;
        for (j=2;(j-1)*a[i]<=a[len-1];++j)
        {
            int num=cnt[j*a[i]-1]-cnt[(j-1)*a[i]-1];
            sum+=ll(num)*a[i]*(j-1); 
        }
        ans=max(sum,ans);
    }
    cout<<ans;
    return 0;
} 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326522529&siteId=291194637