先mark
优化排序
#include <bits/stdc++.h> using namespace std; const int N = 50,M = 1200000; typedef long long ll; ll x[M],y[M]; ll b[M],c[M],S,mx,mn,ans1,ans2; int T,n,a[N],len,m,lg2[M]; int main(){ lg2[0] = -1;for (int i = 1;i < M;i++) lg2[i]=lg2[i/2]+1; while (~scanf("%d",&n)){ mx = 0;mn = 0x7fffffff;mn = mn*mn; S = 0; m = n/2; for (int i = 1;i <= n;i++) { scanf("%d",&a[i]); S += a[i]; } b[0] = 0; for (int i = 1;i <= m;i++){ for (int j = 0;j < (1<<i>>1);j++){ x[j] = b[j]; y[j] = b[j]+a[i]; } int u = 0,v = 0; for (int j = 0;j < (1<<i);j++){ if (u == (1<<i>>1)) b[j] = y[v++]; else if (v == (1<<i>>1)) b[j] = x[u++]; else if (x[u] < y[v]) b[j] = x[u++]; else b[j] = y[v++]; } } c[0] = 0; for (int i = 1;i <= n-m;i++){ for (int j = 0;j < (1<<i>>1);j++){ x[j] = c[j]; y[j] = c[j]+a[m+i]; } int u = 0,v = 0; for (int j = 0;j < (1<<i);j++){ if (u == (1<<i>>1)) c[j] = y[v++]; else if (v == (1<<i>>1)) c[j] = x[u++]; else if (x[u] < y[v]) c[j] = x[u++]; else c[j] = y[v++]; } } int l = (1<<m)-1 , r = (1 << n-m)-1; for (int u = 0,v = r;u <= l;u++){ while (v >= 0 && b[u]+c[v] > S/2){ mn = min(mn,b[u]+c[v]); v--; } if (b[u]+c[v] <= S/2) mx = max(mx,b[u]+c[v]); if (v < r) v++; } if (mx*(S-mx) > mn*(S-mn)) ans1 = mx; else ans1 = mn; mx = 0;mn = 0x7fffffff;mn = mn*mn; for (int u = 0,v = r;u <= l;u++){ while (v >= 0 && (b[u]+c[v])*2 > S/2){ mn = min(mn,(b[u]+c[v])*2); v--; } if ((b[u]+c[v])*2 <= S/2) mx = max(mx,(b[u]+c[v])*2); if (v < r) v++; } if (mx*(S-mx) >= mn*(S-mn)) ans2 = mx; else ans2 = mn; ll s1 = ans1*(S-ans1),s2 = ans2*(S-ans2); if (s1 == s2) printf("%lld ",max(ans1,S-ans2)); else if (s1 < s2) printf("%lld ",S-ans2); else printf("%lld ",ans1); } return 0; }