CF618F Double Knapsack
题意简化
给定两个大小为 n 的集合A,B,要求在每个集合中选出一个子集,使得两个选出来的子集元素和相等
元素范围在 1~n ,n<=1e5
题目连接
题解
考虑前缀和
令A集合的前缀和为SA,B的前缀和SB (有点奇怪,但不重要...)
设SA[n]<SB[n],从0到n枚举i, 对于每个SA[i],找到最小的 SB[j] 使得 SB[j]>=SA[i], 所以\(0<=SB[j]-SA[i]<n\),
所以总共会有n+1个 \(SB[j]-SA[i]\) 而值域却只有n,所以可以保证会有两个及以上重复的数字 (保证有解)
即:
存在 \(SB[j1]-SA[i1]==SB[j2]-SA[i2]\)
显然 B集合中 j2 ~ j1 这段区间的元素和等于A集合中 i2 到 i1 的元素和
代码
#include<bits/stdc++.h>
using namespace std;
#define re register
#define ll long long
#define get getchar()
#define in inline
in int read()
{
int t=0; char ch=get;
while(ch<'0' || ch>'9') ch=get;
while(ch<='9' && ch>='0') t=t*10+ch-'0', ch=get;
return t;
}
const int _=2e6+6;
int n,a[_],b[_];
ll suma[_],sumb[_],x[_],y[_];
bool f[_];
int main()
{
n=read();
for(re int i=1;i<=n;i++)
a[i]=read(),suma[i]=suma[i-1]+a[i];
for(re int i=1;i<=n;i++)
b[i]=read(),sumb[i]=sumb[i-1]+b[i];
int fff=0;
if(sumb[n]<suma[n]) {
for(re int i=1;i<=n;i++) {
ll t=a[i];
a[i]=b[i],b[i]=t;
t=suma[i];
suma[i]=sumb[i],sumb[i]=t;
}
fff=1;
}
int j=0;
for(re int i=0;i<=n;i++) {
while(sumb[j]<suma[i]) j++;
int k=sumb[j]-suma[i];
if(f[k])
{
if(!fff) {
cout<<i-x[k]<<endl;
for(re int p=x[k]+1;p<=i;p++)
cout<<p<<' ';cout<<endl;
cout<<j-y[k]<<endl;
for(re int p=y[k]+1;p<=j;p++)
cout<<p<<' ';cout<<endl;
}
else {
cout<<j-y[k]<<endl;
for(re int p=y[k]+1;p<=j;p++)
cout<<p<<' ';cout<<endl;
cout<<i-x[k]<<endl;
for(re int p=x[k]+1;p<=i;p++)
cout<<p<<' ';cout<<endl;
}
return 0;
}
f[k]=1;
x[k]=i,y[k]=j;
}
}
CF618F Double Knapsack的更多相关文章
- CF618F Double Knapsack 构造、抽屉原理
传送门 首先,选取子集的限制太宽了,子集似乎只能枚举,不是很好做.考虑加强限制条件:将"选取子集"的限制变为"选取子序列"的限制.在接下来的讨论中我们将会知道: ...
- 【CF618F】Double Knapsack(构造)
[CF618F]Double Knapsack(构造) 题面 洛谷 Codeforces 题解 很妙的一道题. 发现找两个数集很不爽,我们强制加强限制,我们来找两个区间,使得他们的区间和相等. 把区间 ...
- Wunder Fund Round 2016 (Div. 1 + Div. 2 combined) F. Double Knapsack 鸽巢原理 构造
F. Double Knapsack 题目连接: http://www.codeforces.com/contest/618/problem/F Description You are given t ...
- Codeforces.618F.Double Knapsack(构造 鸽巢原理)
题目链接 \(Description\) 给定两个大小为\(n\)的可重集合\(A,B\),集合中的元素都在\([1,n]\)内.你需要从这两个集合中各选一个非空子集,使它们的和相等.输出方案. \( ...
- 2018.09.27 codeforces618F. Double Knapsack(抽屉原理+构造)
传送门 思维题. 考虑维护两个数列的前缀和a1,a2,a3,...,ana_1,a_2,a_3,...,a_na1,a2,a3,...,an和b1,b2,b3,...,bnb_1,b_2,b_ ...
- 618F Double Knapsack
传送门 题目大意 分析 代码 #include<iostream> #include<cstdio> #include<cstring> #include<s ...
- CodeForces - 618F Double Knapsack
Discription You are given two multisets A and B. Each multiset has exactly n integers each between 1 ...
- [codeforces 618 F] Double Knapsack (抽屉原理)
题目链接:http://codeforces.com/contest/618/problem/F 题目: 题目大意: 有两个大小为 N 的可重集 A, B, 每个元素都在 1 到 N 之间. 分别找出 ...
- Java:Double Brace Initialization
在我刚刚接触现在这个产品的时候,我就在我们的代码中接触到了对Double Brace Initialization的使用.那段代码用来初始化一个集合: final Set<String> ...
随机推荐
- burp suite 之 Scanner(漏洞扫描)
Scanner选项:是一个进行自动发现 web 应用程序的安全漏洞的工具. 将抓取的包 通过选项卡发送至 Scanner下的Scan queue 首先来介绍 Scanner 下的 lssue acti ...
- day61:Linux:权限管理&rpm软件包管理&yum工具
目录 1.权限管理 2.rpm软件包管理 3.yum工具(联网) 权限管理 1.什么是权限? 权限主要用来约束用户能对系统所做的操作 2.为什么要使用权限? 因为系统中不可能只存在一个root用户,一 ...
- flutter json_annotation和json_serializable处理json数据序列化
flutter json_annotation和json_serializable处理json数据序列化 导包 dependencies: json_annotation: ^2.4.0 dev_de ...
- go分库分表 主从分离例子
网上有很多介绍分库分表的文章,方法很多: 分区表切分 垂直切分 水平切分 区间切分 取模切分 这里不细说 分库分表简单,但后期会带来一系列的难题: 事务 Join 分页 数据库: master和sla ...
- 烽火服务器IPMI远程装机
连接控制台 一.通过vpn拨入进入内网,使用IE浏览器或者火狐等等,连接ilo地址.(需要安装java8.0,各个品牌的服务器需要的不一样) 二.启动虚拟连接控制台,进行控制主机 三.根据截图进行操作 ...
- 达梦数据库_DM8配置MPP主备
为了提高MPP系统可靠性,克服由于单节点故障导致整个系统不能继续正常工作,DM 在普通的MPP系统基础上,引入主备守护机制,将MPP节点作为主库节点,增加备库作为备份节点,必要时可切换为主库代替故障节 ...
- 跟着动画学习 TCP 三次握手和四次挥手
TCP三次握手和四次挥手的问题在面试中是最为常见的考点之一.很多读者都知道三次和四次,但是如果问深入一点,他们往往都无法作出准确回答. 本篇尝试使用动画来对这个知识点进行讲解,期望读者们可以更加简单地 ...
- C#与sql进行图片存取
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Da ...
- Rust之路(4)——所有权
[未经书面同意,严禁转载] -- 2020-10-14 -- 所有权是Rust的重中之重(这口气咋像高中数学老师 WTF......). 所有权是指的对内存实际存储的数据的访问权(包括读取和修改),在 ...
- .net core中的那些常用的日志框架(Serilog篇)
前言 上文说到Nlog日志框架,感觉它功能已经很强大,今天给大家介绍一个很不错的日志框架Serilog,根据我的了解,感觉它最大的优势是,结构化日志,它输出的日志是Json的格式,如果你使用的是Mon ...