[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;
}

猜你喜欢

转载自www.cnblogs.com/skylee03/p/10170698.html
今日推荐