【CF618F】 Double Knapsack

题目

题目描述
You are given two multisets AA and BB . Each multiset has exactly nn integers each between 11 and nn inclusive. Multisets may contain multiple copies of the same number.

You would like to find a nonempty subset of AA and a nonempty subset of BB such that the sum of elements in these subsets are equal. Subsets are also multisets, i.e. they can contain elements with equal values.

If no solution exists, print -1−1 . Otherwise, print the indices of elements in any such subsets of AA and BB that have the same sum.

输入格式
The first line of the input contains a single integer nn ( 1<=n<=10000001<=n<=1000000 ) — the size of both multisets.

The second line contains nn integers, denoting the elements of AA . Each element will be between 11 and nn inclusive.

The third line contains nn integers, denoting the elements of BB . Each element will be between 11 and nn inclusive.

输出格式
If there is no solution, print a single integer -1−1 . Otherwise, your solution should be printed on four lines.

The first line should contain a single integer k_{a}k
a

, the size of the corresponding subset of AA . The second line should contain k_{a}k
a

distinct integers, the indices of the subset of AA .

The third line should contain a single integer k_{b}k
b

, the size of the corresponding subset of BB . The fourth line should contain k_{b}k
b

distinct integers, the indices of the subset of BB .

Elements in both sets are numbered from 11 to nn . If there are multiple possible solutions, print any of them.

题意翻译
给你两个可重集 A, B ,  A、B 的元素个数都为n且n⩽1000000 , 它们中每个元素的大小x∈[1,n] 。 请你分别找出A ,B 的可重子集, 使得它们中的元素之和相等。

输入格式:

第一行为一个整数n, 表示两个子集的大小。

第二、三行皆为n个整数,分别表示A 、B 的元素。

输出格式:

如果无解, 请输出-1。如果有解, 第一行输出A 的可重子集中元素的个数,第二行输出该子集中元素在A 中对应的下标;第三行输出B 的可重子集中元素的个数, 第四行输出该子集中元素在B 中对应的下标。

数据可能存在多组解, 输出一组即可。

感谢@LPA20020220 提供的翻译

输入输出样例
输入 #1复制
10
10 10 10 10 10 10 10 10 10 10
10 9 8 7 6 5 4 3 2 1
输出 #1复制
1
2
3
5 8 10
输入 #2复制
5
4 4 3 3 3
2 2 2 2 5
输出 #2复制
2
2 3
2
3 5

思路

假设 a a a数组算到最后总和比 b b b大,我们现在考虑对于每一个 i i i,找出最大的 t a ta ta满足KaTeX parse error: Expected 'EOF', got '&' at position 5: sa_i&̲gt;=sb_{ta},其中 s a sa sa a a a数组的前缀和, s b sb sb b b b数组的前缀和。
这个不等式可以写成 0 < = S a i − S b t a < n 0<=Sai-Sbta<n 0<=SaiSbta<n,因为只要大于等于 n n n我们就可以继续向前移动 t a ta ta
我们从0开始统计这个 s a i − s b t a sa_i - sb_{ta} saisbta的值,那么根据鸽巢原理,一共 n + 1 n+1 n+1个数字分配在 n n n个笼子里,至少有两对是相等的,也就说不存在无解的情况。

代码

#include<bits/stdc++.h>
#define pi acos(-1.0)

using namespace std;
const int ms = 1e6 + 77;

int n,lx;

ll sa[ms],sb[ms];

struct in
{
	int x,y;
}pos[ms];

int main()
{
	re(n);
	for(int i = 1; i <= n; i ++)
		re(sa[i]),sa[i] += sa[i - 1];
	for(int i = 1; i <= n; i ++)
		re(sb[i]),sb[i] += sb[i - 1];
	for(int i = 0; i <= n; i ++)
		pos[i] = (in){-1,-1};
	bool f = 0;
	if(sa[n] < sb[n])
		swap(sa,sb),f = 1;
	int i,ta = 0; ll v;
	for(i = 0; i <= n; i ++)
	{
		while(sa[i] >= sb[ta + 1] && ta + 1 <= n)
			ta ++;
		v = sa[i] - sb[ta];
		if(pos[v].x == -1)
			pos[v] = (in){i,ta};
		else
			break;
	}
	if(f)
		swap(sa,sb),swap(i,ta),swap(pos[v].x,pos[v].y);
	printf("%d\n",i - pos[v].x);
	for(int j = pos[v].x + 1; j <= i; j ++)
		printf("%d ",j);
	printf("\n");
	printf("%d\n",ta - pos[v].y);
	for(int j = pos[v].y + 1; j <= ta; j ++)
		printf("%d ",j);
	system("pause");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值