贪心可过,先把序列从大到小排序,求出前缀和pre[i],在对于每个数,求出它前面和后面的第一个奇数和偶数。对于每个询问k,如果pre[k]是奇数就直接输出,否则就拿去pre[k]中最小的奇数再添一个k+1到n中最大的偶数,或者拿去最小的偶数添一个奇数,这两种情况取max输出就是答案。而无法拿去或添加就对应无解的情况。
注意,根据数据范围推得需要用long long。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define M 1000001
typedef unsigned long long L;
using namespace std;
L n, a[M], pre[M], odd[M], eve[M], odd2[M], eve2[M], m, q;
bool cmp(L a, L b){
return a > b;
}
int main()
{
scanf("%lld", &n);
for(int i = 1; i <= n; i++)
scanf("%lld", a+i);
sort(a+1, a+n+1, cmp);
for(int i = 1; i <= n; i++)
pre[i] = a[i]+pre[i-1];
for(int i = 1; i <= n; i++){
if(a[i]&1){
odd2[i] = a[i];
eve2[i] = eve2[i-1];
}else{
eve2[i] = a[i];
odd2[i] = odd2[i-1];
}
}
for(int i = n; i > 0; i--){
if(a[i]&1){
odd[i-1] = a[i];
eve[i-1] = eve[i];
}else{
eve[i-1] = a[i];
odd[i-1] = odd2[i];
}
}
scanf("%lld", &m);
while(m--){
scanf("%d", &q);
if(pre[q]&1) printf("%lld\n", pre[q]);
else{
L ans = 0;
L o = odd[q], o2 = odd2[q], e = eve[q], e2 = eve2[q];
if(o && e2) ans = pre[q]-e2+o;
if(e && o2) ans = max(pre[q]-o2+e, ans);
if(ans) printf("%lld\n", ans);
else printf("-1\n");
}
}
}