zoukankan      html  css  js  c++  java
  • BZOJ 3721: PA2014 Final Bazarek

    3721: PA2014 Final Bazarek

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 645  Solved: 261
    [Submit][Status][Discuss]

    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
    4

    Sample Output

    7
    9
    -1

    HINT

     

    Source

    [Submit][Status][Discuss]

    先对所有数字按照从大到小的顺序排序,然后维护前缀和,以及最小前缀(奇数/偶数),最大后缀(奇数/偶数)。

    当询问K个的时候,如果sum[k]凑巧是个奇数,那么答案就是sum[k],否则就考虑用一个未添加的奇数换一个已添加的偶数,或是用一个未添加的偶数换一个已添加的奇数,二者取其大。

     1 #include <bits/stdc++.h>
     2 
     3 template <class T>
     4 inline void read(T &x) {
     5     char c = getchar(); x = 0;
     6     while (c < '0')
     7         c = getchar();
     8     while (c >= '0') {
     9         x = x*10 + c - '0';
    10         c = getchar();
    11     }
    12 }
    13 
    14 template <class T>
    15 inline T Max(const T &a, const T &b) {
    16     return a > b ? a : b;
    17 }
    18 
    19 template <class T>
    20 inline T Min(const T &a, const T &b) {
    21     return a < b ? a : b;
    22 }
    23 
    24 inline int cmp(const void *a, const void *b) {
    25     return - *(int *)a + *(int *)b;
    26 }
    27 
    28 typedef long long longint;
    29 
    30 const int inf = 2e9 + 9;
    31 
    32 const int siz = 1000005;
    33 
    34 int n, m;
    35 int num[siz];
    36 int min[siz][2];
    37 int max[siz][2];
    38 longint sum[siz];
    39 
    40 inline void prework(void) {
    41     qsort(num + 1, n, sizeof(int), cmp);
    42     
    43     memset(sum, 0, sizeof(sum));
    44     
    45     for (int i = 0; i < siz; ++i)
    46         min[i][0] = min[i][1] = inf,
    47         max[i][0] = max[i][1] = -inf;
    48     
    49     for (int i = 1; i <= n; ++i)
    50         sum[i] = sum[i - 1] + num[i];
    51     
    52     for (int i = 1; i <= n; ++i) {
    53         int a = num[i] & 1, b = a ^ 1;
    54         min[i][a] = num[i];
    55         min[i][b] = min[i - 1][b];
    56     }
    57     
    58     for (int i = n; i >= 1; --i) {
    59         int a = num[i] & 1, b = a ^ 1;
    60         max[i][a] = num[i];
    61         max[i][b] = max[i + 1][b];
    62     }
    63 }
    64 
    65 inline bool judge(int k) {
    66     return 
    67         (min[k][0] == inf || max[k + 1][1] == -inf)
    68     &&  (min[k][1] == inf || max[k + 1][0] == -inf);
    69 }
    70 
    71 inline void query(int k) {
    72     if (sum[k] & 1)
    73         printf("%lld
    ", sum[k]);
    74     else if (judge(k))puts("-1");
    75     else printf("%lld
    ", 
    76         sum[k] + Max(
    77             - min[k][0] + max[k + 1][1],
    78             - min[k][1] + max[k + 1][0])
    79         );
    80 }
    81 
    82 signed main(void) {
    83     read(n);
    84     
    85     for (int i = 1; i <= n; ++i)
    86         read(num[i]);
    87         
    88     prework();
    89         
    90     read(m);
    91     
    92     for (int i = 1, k; i <= m; ++i)
    93         read(k), query(k);
    94 }

    @Author: YouSiki

  • 相关阅读:
    远程调试 ASP.NET MVC 项目
    两行代码搞定 JavaScript 的日期验证
    ASP.NET MVC 静态资源打包和压缩问题小记
    CodeSmith7连接Mysql
    网站开发烦心记-1
    感悟还是教训,或者。。。
    可以断点续传的scp
    CTP报单状态
    android studio 0.8.8下载
    期货结算单查询
  • 原文地址:https://www.cnblogs.com/yousiki/p/6145057.html
Copyright © 2011-2022 走看看