ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

题解 CF618F Double Knapsack

2022-03-27 20:03:35  阅读:132  来源: 互联网

标签:le CF618F 题解 int Knapsack bukj sb sa buki


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

令 $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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有