[PA2014]Bazarek

[PA2014]Bazarek

题目大意:

\(n(n\le10^6)\)件商品,\(m(m\le10^6)\)次询问。每次询问若选出其中的\(k\)个,要求它们的总价为奇数,求最大可能的总价。

思路:

从大到小排序取前\(k\)个,若不是奇数就去掉已选最小偶数/奇数再加上未选最大奇数/偶数。

源代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
#include<functional>
inline int getint() {
	register char ch;
	while(!isdigit(ch=getchar()));
	register int x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return x;
}
typedef long long int64;
const int N=1e6+1;
int64 a[N],min[N][2],max[N][2];
int main() {
	const int n=getint();
	for(register int i=1;i<=n;i++) {
		a[i]=getint();
	}
	std::sort(&a[1],&a[n]+1,std::greater<int64>());
	for(register int i=1;i<=n;i++) {
		if(i!=1) {
			min[i][0]=min[i-1][0];
			min[i][1]=min[i-1][1];
		}
		min[i][a[i]&1]=a[i];
	}
	for(register int i=n;i>=1;i--) {
		if(i!=n) {
			max[i][0]=max[i+1][0];
			max[i][1]=max[i+1][1];
		}
		max[i][a[i]&1]=a[i];
	}
	for(register int i=1;i<=n;i++) {
		a[i]+=a[i-1];
	}
	const int m=getint();
	for(register int i=0;i<m;i++) {
		const int k=getint();
		if(a[k]&1) {
			printf("%lld\n",a[k]);
			continue;
		}
		int64 ans=0;
		if(k!=n&&min[k][0]&&max[k+1][1]) {
			ans=std::max(ans,a[k]-min[k][0]+max[k+1][1]);
		}
		if(k!=n&&min[k][1]&&max[k+1][0]) {
			ans=std::max(ans,a[k]-min[k][1]+max[k+1][0]);
		}
		printf("%lld\n",ans?:-1);
	}
	return 0;
}
posted @ 2018-12-24 20:05  skylee03  阅读(147)  评论(0编辑  收藏  举报