bzoj 3721 Final Bazarek
题目大意:
n个数 选k个使和为奇数且最大
思路:
可以先将这n个数排序
然后先去最大的k个数 若和为奇数则直接输出
为偶数可以用没选的最大的奇数替换选了的最小的偶数或用没选的最大的偶数替换选了的最小的奇数
预处理出4个数组即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #define ll long long 11 #define inf 2139062143 12 #define MAXN 1001000 13 using namespace std; 14 inline ll read() 15 { 16 ll x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) x=x*10+ch-'0',ch=getchar(); 19 return x*f; 20 } 21 ll n,a[MAXN],T,sum[MAXN],mn[MAXN][2],mx[MAXN][2]; 22 int main() 23 { 24 n=read();ll x,res; 25 for(ll i=1;i<=n;i++) a[i]=read(); 26 sort(a+1,a+n+1); 27 for(ll i=1;i<=n;i++) sum[i]=sum[i-1]+a[i]; 28 for(ll i=1;i<=n;i++) mx[i][a[i]&1]=a[i],mx[i][(a[i]&1)^1]=mx[i-1][(a[i]&1)^1]; 29 mn[n+1][1]=mn[n+1][0]=inf; 30 for(ll i=n;i>=1;i--) mn[i][a[i]&1]=a[i],mn[i][(a[i]&1)^1]=mn[i+1][(a[i]&1)^1]; 31 T=read(); 32 while(T--) 33 { 34 x=read(); 35 res=sum[n]-sum[n-x]; 36 if(res&1) {printf("%lld\n",res);continue ;} 37 res=-1; 38 if(mn[n-x+1][0]!=inf&&mx[n-x][1]) res=sum[n]-sum[n-x]-mn[n-x+1][0]+mx[n-x][1]; 39 if(mn[n-x+1][1]!=inf&&mx[n-x][0]) res=max(res,sum[n]-sum[n-x]-mn[n-x+1][1]+mx[n-x][0]); 40 printf("%lld\n",res); 41 } 42 }