先成套买,剩下的的凑,凑不齐的退一套继续凑。
#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 ",ans); continue; } int r = n / gcd(n,k); if (f[r] != 0) { printf("%lld ",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 ",ans); f[r] = ans; } return 0; }