其他分享
首页 > 其他分享> > 题解 CF618F Double Knapsack

题解 CF618F Double Knapsack

作者:互联网

首先,这个要求的解的形式太过自由,选择一个子集不是很好处理。于是我们可以套路地对其加以限制,变成选择两段区间,使他们和相同。

令 $sa_i$ 和 $sb_i$ 分别表示 $a$ 和 $b$ 序列的前缀和,此处我们假设 $sa_n\le sb_n$。

那么我们可以枚举 $i$,找到一个最大的满足 $sb_j\le sa_i$ 的 $j$,由于 $sa_n\le sb_n$,所以容易发现,$sa_i-sb_j \in [0,n-1]$。对于 $n+1$ 种 $sa_i-sb_j$ 只有 $n$ 种取值,根据抽屉原理可知肯定有两对 $sa_i-sb_j$ 是相同的:$sa_{i_1}-sb_{j_1}=sa_{i_2}-sb_{j_2}$,可以得到 $sa_{i_2}-sa_{i_1}=sb_{j_2}-sb_{j_1}$ 所以所求答案的区间即为 $a[i_1+1...i_2]$ 和 $b[j_1+1...j_2]$。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define fi first
#define se second
const int N = 1e6 + 5;
int n, a[N], b[N], buki[N], bukj[N], ok;
ll sa[N], sb[N];

int main() {
    memset(buki, -1, sizeof(buki));
    memset(bukj, -1, sizeof(bukj));
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d", &a[i]), sa[i] = sa[i - 1] + a[i];
    for(int i = 1; i <= n; i++)
        scanf("%d", &b[i]), sb[i] = sb[i - 1] + b[i];
    if(sa[n] > sb[n]) {
        ok = 1;
        for(int i = 1; i <= n; i++)
            swap(a[i], b[i]), swap(sa[i], sb[i]);
    }
    for(int i = 0, j = 0; i <= n; i++) {
        while(j + 1 <= n && sa[i] >= sb[j + 1]) j++;
        if(buki[sa[i] - sb[j]] != -1) {
            if(!ok) {
                printf("%d\n", i - buki[sa[i] - sb[j]]);
                for(int k = buki[sa[i] - sb[j]] + 1; k <= i; k++) printf("%d ", k);
                printf("\n%d\n", j - bukj[sa[i] - sb[j]]);
                for(int k = bukj[sa[i] - sb[j]] + 1; k <= j; k++) printf("%d ", k);
                printf("\n");    
            } else {
                printf("%d\n", j - bukj[sa[i] - sb[j]]);
                for(int k = bukj[sa[i] - sb[j]] + 1; k <= j; k++) printf("%d ", k);
                printf("\n%d\n", i - buki[sa[i] - sb[j]]);
                for(int k = buki[sa[i] - sb[j]] + 1; k <= i; k++) printf("%d ", k);
                printf("\n");
            }
            return 0;
        }
        buki[sa[i] - sb[j]] = i, bukj[sa[i] - sb[j]] = j;
    }
    return 0;
}

 

标签:le,CF618F,题解,int,Knapsack,bukj,sb,sa,buki
来源: https://www.cnblogs.com/qshjydzh/p/16064088.html