zoukankan      html  css  js  c++  java
  • 「NOI2019d1t3」序列

    「NOI2019d1t3」序列

    题目链接

    (Description)

    长度为 (n (n leq 10 ^ 6)) 的两个序列 (a, b),要求各选 (K (K leq n)) 个数满足条件:

    至少有 (L (L leq K)) 个数在序列中的位置相同;

    满足上述条件时,使得选出数的和最大。

    输出最大的和。

    (Solution)

    显然可以费用流,模型如下:

    (S - A_i (1, a_i))(A_i - B_i (1, 0))(B_i - R (1, b_i))(R - T (K, 0))

    (A_i - P (1, 0))(P - Q (K - L, 0))(Q - B_i (1, 0))

    如果 (P - Q) 未流满,先考虑它肯定最优;

    如果流满,那么只有两种选择:

    1.选位置相同的一对;
    2.选 (A) 中的最大值 (A_i)(B)(A_j) 已经被选过的最大值 (B_j),反之同理。

    如果某一对 (A_i)(B_i) 在两此不同的增广里被选择,就不占用 (P-Q) 的流量。

    模拟上述过程即可。

    时间复杂度:(O (T n log_2 n))

    (Source)

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    int in() {
        int x = 0; char c = getchar(); bool f = 0;
        while (c < '0' || c > '9')
            f |= c == '-', c = getchar();
        while (c >= '0' && c <= '9')
            x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
        return f ? -x : x;
    }
    template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
    template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }
    
    const int N = 1e6 + 5;
    
    int n, K, L;
    int a[N], b[N];
    
    typedef std::pair<int, int> pii;
    std::priority_queue<pii> q1, q2, h1, h2, q;
    int vis1[N], vis2[N];
    
    void prep() {
        memset(vis1, 0, sizeof(vis1));
        memset(vis2, 0, sizeof(vis2));
        while (!q1.empty()) q1.pop();
        while (!q2.empty()) q2.pop();
        //printf("%d
    ", h1.size());
        while (!h1.empty()) h1.pop();
        while (!h2.empty()) h2.pop();
        while (!q.empty()) q.pop();
        for (int i = 1; i <= n; ++i) {
            q1.push(pii(a[i], i)), q2.push(pii(b[i], i));
            q.push(pii(a[i] + b[i], i));
        }
    }
    
    long long work() {
        long long ret = 0;
        int now = 0;
        for (int i = 1; i <= K; ++i) {
            if (now < K - L) {
                int u, v;
                while (!q1.empty()) {
                    u = q1.top().second; q1.pop();
                    if (!vis1[u])
                        break;
                }
                while (!q2.empty()) {
                    v = q2.top().second; q2.pop();
                    if (!vis2[v])
                        break;
                }
                if (u != v) {
                    if (!vis2[u])
                        h2.push(pii(b[u], u));
                    if (!vis1[v])
                        h1.push(pii(a[v], v));
                }
                if (vis2[u] && vis1[v])
                    --now;
                else if (!vis2[u] && !vis1[v] && u != v)
                    ++now;
                vis1[u] = vis2[v] = 1;
                ret += a[u] + b[v];
            } else {
                int u1 = 0, u2 = 0, s1 = 0;
                while (!q1.empty()) {
                    u1 = q1.top().second;
                    if (!vis1[u1])
                        break;
                    q1.pop();
                }
                while (!h2.empty()) {
                    u2 = h2.top().second;
                    if (!vis2[u2])
                        break;
                    h2.pop();
                }
                if (u2 && !vis2[u2])
                    s1 = a[u1] + b[u2];
    
                int v2 = 0, v1 = 0, s2 = 0;
                while (!q2.empty()) {
                    v2 = q2.top().second;
                    if (!vis2[v2])
                        break;
                    q2.pop();
                }
                while (!h1.empty()) {
                    v1 = h1.top().second;
                    if (!vis1[v1])
                        break;
                    h1.pop();
                }
                if (v1 && !vis1[v1])
                    s2 = a[v1] + b[v2];
    
                int w = 0, s3 = 0;
                while (!q.empty()) {
                    w = q.top().second;
                    if (!vis1[w] && !vis2[w])
                        break;
                    q.pop();
                }
                if (!vis1[w] && !vis2[w])
                    s3 = a[w] + b[w];
    
                //printf("%d %d  %d %d  %d
    ", u1, u2, v1, v2, w);
                //printf("%d %d %d
    ", s1, s2, s3);
                if (w && s3 > s1 && s3 > s2) {
                    q.pop();
                    vis1[w] = vis2[w] = 1;
                    ret += s3;
                } else if (s1 >= s3 && (s1 > s2 || (s1 == s2 && vis2[u1] > vis1[v2]))) {
                    q1.pop(), h2.pop();
                    vis1[u1] = 1, vis2[u2] = 1;
                    if (vis2[u1])
                        --now;
                    else
                        h2.push(pii(b[u1], u1));
                    ret += s1;
                } else {
                    //printf("%d
    ", h1.size());
                    //printf("%d %d %d
    ", s1, s2, s3);
                    q2.pop(), h1.pop();
                    vis2[v2] = 1, vis1[v1] = 1;
                    if (vis1[v2])
                        --now;
                    else
                        h1.push(pii(a[v2], v2));
                    ret += s2;
                }
    
            }
            //printf("%d %d
    ", u, v);
        }
        return ret;
    }
    
    int main() {
        //freopen("in", "r", stdin);
        //freopen("out2", "w", stdout);
        int tim = in();
        while (tim--) {
            n = in(), K = in(), L = in();
            for (int i = 1; i <= n; ++i)
                a[i] = in();
            for (int i = 1; i <= n; ++i)
                b[i] = in();
            prep();
            printf("%lld
    ", work());
        }
        return 0;
    }
    
  • 相关阅读:
    remove white space from read
    optimize the access speed of django website
    dowload image from requests
    run jupyter from command
    crawl wechat page
    python version 2.7 required which was not found in the registry windows 7
    health
    alternate rows shading using conditional formatting
    word
    【JAVA基础】static 关键字
  • 原文地址:https://www.cnblogs.com/15owzLy1-yiylcy/p/12983167.html
Copyright © 2011-2022 走看看