题意:
Description
有n件商品,选出其中的k个,要求它们的总价为奇数,求最大可能的总价。
Input
第一行一个整数n(1<=n<=1000000),表示商品数量。
接下来一行有n个整数,表示每件商品的价格,范围在[1,10^9]。
接下来一行有一个整数m(1<=m<=1000000),表示询问数量。
接下来m行,每行一个整数k[i](1<=k[i]<=n)。Output
对于每个询问,输出一行表示保证奇数的情况下最大的总价。若无法满足要求,输出-1。
Sample Input
4
4 2 1 3
3
2
3
4Sample Output
7
9
-1
思路:贪心。
提交:2次(第一次是因为写了文件$qwq$,然后对拍时发现和网上的标程不一样(但窝觉得他的程序错了、、、好像Inf开小了))
题解:
先$sort$,取出前$k$大,若是奇数直接输出,否则找到前$k$大中的最小的奇数(或偶数),拿剩下的数中的最大的偶数(或奇数)换掉。
应该是可以O(n)预处理+查询。。
但是脑抽写了树状数组$qwq$
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; #define ull unsigned long long #define ll long long #define R register ll #define pause (for(R i=1;i<=10000000000;++i)) #define In freopen("NOIPAK++.in","r",stdin) #define Out freopen("out.out","w",stdout) namespace Fread { static char B[1<<15],*S=B,*D=B; #ifndef JACK #define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++) #endif inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix; if(ch==EOF) return EOF; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } inline bool isempty(const char& ch) {return (ch<=36||ch>=127);} inline void gs(char* s) { register char ch; while(isempty(ch=getchar())); do *s++=ch; while(!isempty(ch=getchar())); } } using Fread::g; using Fread::gs; namespace Luitaryi { const int Inf=0x3f3f3f3f,N=1000010; int n,m; int a[N],c[2][N],d[2][N]; ll sum[N],ans; inline int lbt(int x) {return x&-x;} inline void add(int whi,int pos,int inc) { for(;pos<=n;pos+=lbt(pos)) c[whi][pos]=max(c[whi][pos],inc); } inline int query(int whi,int pos) { R ret=0; for(;pos;pos-=lbt(pos)) ret=max((ll)c[whi][pos],ret); return ret; } inline void addn(int whi,int pos,int inc) { for(;pos<=n;pos+=lbt(pos)) d[whi][pos]=min(d[whi][pos],inc); } inline int queryn(int whi,int pos) { R ret=Inf; for(;pos;pos-=lbt(pos)) ret=min((ll)d[whi][pos],ret); return ret; } inline void main() { n=g(); memset(d,0x3f,sizeof(d)); for(R i=1;i<=n;++i) a[i]=g(); sort(a+1,a+n+1); for(R i=1;i<=n;++i) add(a[i]&1,i,a[i]),addn(a[i]&1,n-i+1,a[i]); for(R i=1;i<=n;++i) sum[i]=sum[i-1]+a[i]; m=g(); for(R i=1,k;i<=m;++i) { k=g(); ans=sum[n]-sum[n-k]; if(ans&1) printf("%lld ",ans); else { register bool flg=true; R ans0=0,ans1=0; R tmp0=queryn(0,k),tmp1=queryn(1,k); if(tmp0!=Inf&&k!=n) { R swp=query(1,n-k); if(swp!=0) ans0=ans-(tmp0-swp),flg=false; } if(tmp1!=Inf&&k!=n) { R swp=query(0,n-k); if(swp!=0) ans1=ans-(tmp1-swp),flg=false; } if(flg) printf("-1 "); else printf("%lld ",max(ans1,ans0)); } } } } signed main() { Luitaryi::main(); return 0; }
2019.07.14