1. 程式人生 > 其它 >P5470 [NOI2019] 序列

P5470 [NOI2019] 序列

https://www.luogu.com.cn/problem/P5470

模擬費用流硬分析討論即可

具體看
https://djy-juruo.blog.luogu.org/solution-p5470

code:

#include<bits/stdc++.h>
#define N 200050
#define ll long long
#define pii pair<ll, int> 
#define fi first
#define se second
using namespace std;
priority_queue<pii > q1, q2, q3, q4, q5, q6;
void clr() {
    while(q1.size()) q1.pop();
    while(q2.size()) q2.pop();
    while(q3.size()) q3.pop();
    while(q4.size()) q4.pop();
    while(q5.size()) q5.pop();
    while(q6.size()) q6.pop();
}
struct A {
    int x, id;
} a[N], b[N];
int cmp(A x, A y) {
    return x.x > y.x;
}
int cmpp(A x, A y) {
    return x.id < y.id;
}
int n, K, L, id[N];
const int inf = 2e16;
void solve() {
    clr();
    scanf("%d%d%d", &n, &K, &L);
    for(int i = 1; i <= n + 3; i ++) id[i] = 0;
    for(int i = 1; i <= n; i ++) scanf("%d", &a[i].x), a[i].id = i;
    for(int i = 1; i <= n; i ++) scanf("%d", &b[i].x), b[i].id = i;
    sort(a + 1, a + 1 + n, cmp), sort(b + 1, b + 1 + n, cmp);
    ll ans = 0;
    for(int i = 1; i <= K; i ++) ans += a[i].x, id[a[i].id] = 1;
    for(int i = 1; i <= K; i ++) ans += b[i].x, id[b[i].id] += 2;
    sort(a + 1, a + 1 + n, cmpp), sort(b + 1, b + 1 + n, cmpp);
    
    q1.push(make_pair(- inf, n + 1)), id[n + 1] = 2;
    q2.push(make_pair(- inf, n + 2)), id[n + 2] = 1;
    q3.push(make_pair(- inf, n + 1));
    q4.push(make_pair(- inf, n + 2));
    q5.push(make_pair(- inf, 0)); id[0] = 0;
    q6.push(make_pair(- inf, n + 3)); id[n + 3] = 3;

    for(int i = 1; i <= n; i ++) {
        q1.push(make_pair(a[i].x, i));
        q2.push(make_pair(-a[i].x, i));
        q3.push(make_pair(b[i].x, i));
        q4.push(make_pair(-b[i].x, i));
        q5.push(make_pair(a[i].x + b[i].x, i));
        q6.push(make_pair(-a[i].x - b[i].x, i));
    }

    for(int i = 1; i <= n; i ++) if(id[i] == 3) L --;

    //for(int i = 1; i <= n; i ++) printf("%d ", id[i]); printf("\n");
    L = max(L, 0);
    while(L --) {
        while(id[q1.top().se] != 2) q1.pop();
        while(id[q2.top().se] != 1) q2.pop();
        while(id[q3.top().se] != 1) q3.pop();
        while(id[q4.top().se] != 2) q4.pop();
        while(id[q5.top().se] != 0) q5.pop();
        while(id[q6.top().se] != 3) q6.pop();

        pii x1 = q1.top(), x2 = q2.top(), x3 = q3.top(), x4 = q4.top(), x5 = q5.top(), x6 = q6.top();
        ll mx = -inf; int op = 0;
        if(x3.fi + x4.fi > mx) mx = x3.fi + x4.fi, op = 1;
        if(x1.fi + x2.fi > mx) mx = x1.fi + x2.fi, op = 2;
        if(x2.fi + x4.fi + x5.fi > mx) mx = x2.fi + x4.fi + x5.fi, op = 3;
        if(x1.fi + x3.fi + x6.fi > mx) mx = x1.fi + x3.fi + x6.fi, op = 4;
        ans += mx;

        if(op == 1) {
            int x = x3.se;
            id[x] = 3;
            q6.push(make_pair(-a[x].x - b[x].x, x));

            x = x4.se;
            id[x] = 0;
            q5.push(make_pair(a[x].x + b[x].x, x));
        }
        if(op == 2) {
            int x = x1.se;
            id[x] = 3;
            q6.push(make_pair(-a[x].x - b[x].x, x));

            x = x2.se;
            id[x] = 0;
            q5.push(make_pair(a[x].x + b[x].x, x));
        }
        if(op == 3) {
            int x = x2.se;
            id[x] = 0;
            q5.push(make_pair(a[x].x + b[x].x, x));

            x = x4.se;
            id[x] = 0;
            q5.push(make_pair(a[x].x + b[x].x, x)); 

            x = x5.se;
            id[x] = 3;
            q6.push(make_pair(-a[x].x - b[x].x, x));            
        }
        if(op == 4) {
            int x = x1.se;
            id[x] = 3;
            q6.push(make_pair(-a[x].x - b[x].x, x));

            x = x3.se;
            id[x] = 3;
            q6.push(make_pair(-a[x].x - b[x].x, x));

            x = x6.se;
            id[x] = 0;
            q5.push(make_pair(a[x].x + b[x].x, x)); 
        }
    }
    printf("%lld\n", ans);
}
int t;
int main() {
    //  freopen("a.in","r",stdin);
    //  freopen("a.out","w",stdout);
    scanf("%d", &t);
    while(t --) solve();
    return 0;
}
/*
1
6 4 1
1 5 8 3 2 4
2 6 9 3 1 7
*/