luoguP6188 [NOI Online 入门组]文具订购 打表

先成套买,剩下的的凑,凑不齐的退一套继续凑。

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
int n,m,k;
ll ans,a[210000],f[210000];
int gcd(int a,int b)
{
    if (b == 0)
        return a;
    return gcd(b,a%b);
}
bool cmp(ll a,ll b)
{
    return a > b;
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int i = 1;i <= n;i++)
        scanf("%lld",&a[i]);
    sort(a + 1,a + n + 1,cmp);
    for (int i = 1;i <= m;i++)
    {
        ans = 0;
        scanf("%d",&k);
        if (k == 0)
        {
            for (int j = 1;j <= n;j++)
                ans += a[j] * a[j];
            printf("%lld\n",ans);
            continue;
        }
        int r = n / gcd(n,k);
        if (f[r] != 0)
        {
            printf("%lld\n",f[r]);
            continue;
        }
        for (int c = 1;c <= n /r;c++)
        {
            ans += a[(c - 1) * r + 1] * a[(c - 1) * r + 2];
            ans += a[(c - 1) * r + r - 1] * a[(c - 1) * r + r];
            for (int j = (c - 1) * r + 1;j <= (c - 1) * r + r - 2;j++)
                ans += a[j] * a[j + 2]; 
        }
        printf("%lld\n",ans);
        f[r] = ans; 
    }
    return 0;
}

 

posted @ 2020-03-14 23:54  IAT14  阅读(227)  评论(0编辑  收藏  举报