【CF618F】Double Knapsack(构造)
【CF618F】Double Knapsack(构造)
题面
题解
很妙的一道题。
发现找两个数集很不爽,我们强制加强限制,我们来找两个区间,使得他们的区间和相等。
把区间和转为前缀和的形式,现在问题变成了,给定两个单增的数列\(A,B\),不妨令\(A_n<B_n\)找到\(l1,r1,l2,r2\),满足\(A_{r1}-A_{l1}=B_{r2}-B_{l2}\),换一下就是\(B_{l2}-A_{l1}=B_{r2}-A_{r1}\)。
那么对于\(A\)数列的每个\(i\le [0,n]\)我们都一定可以在\(B\)数量中找到一个最小的\(j\)使得\(0\le B_j-A_i<n\),证明就是因为每个元素都小于\(n\)。
那么这样子一共会产生\(n+1\)个差,根据鸽巢原理,必定有两个差相等,那么等价于我们构造出了一组答案。
这题最妙的地方就是在于本来限制相当宽松,我们强制加强了限制,反而能够更容易的得到解了。
#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
#define MAX 1000100
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,a[MAX],b[MAX],fl;ll A[MAX],B[MAX];
void Output(int l1,int r1,int l2,int r2)
{
if(fl)swap(l1,l2),swap(r1,r2);
printf("%d\n",r1-l1);for(int i=l1+1;i<=r1;++i)printf("%d ",i);puts("");
printf("%d\n",r2-l2);for(int i=l2+1;i<=r2;++i)printf("%d ",i);puts("");
exit(0);
}
int main()
{
n=read();
for(int i=1;i<=n;++i)A[i]=A[i-1]+read();
for(int i=1;i<=n;++i)B[i]=B[i-1]+read();
if(A[n]>B[n])swap(A,B),fl=1;
for(int i=0;i<n;++i)a[i]=-1;
for(int i=0,j=0;i<=n;++i)
{
while(B[j]<A[i])++j;
int d=B[j]-A[i];
if(~a[d])Output(a[d],i,b[d],j);
a[d]=i;b[d]=j;
}
puts("-1");
return 0;
}
【CF618F】Double Knapsack(构造)的更多相关文章
- CF618F Double Knapsack 构造、抽屉原理
传送门 首先,选取子集的限制太宽了,子集似乎只能枚举,不是很好做.考虑加强限制条件:将"选取子集"的限制变为"选取子序列"的限制.在接下来的讨论中我们将会知道: ...
- Codeforces.618F.Double Knapsack(构造 鸽巢原理)
题目链接 \(Description\) 给定两个大小为\(n\)的可重集合\(A,B\),集合中的元素都在\([1,n]\)内.你需要从这两个集合中各选一个非空子集,使它们的和相等.输出方案. \( ...
- CF618F Double Knapsack
题意简化 给定两个大小为 n 的集合A,B,要求在每个集合中选出一个子集,使得两个选出来的子集元素和相等 元素范围在 1~n ,n<=1e5 题目连接 题解 考虑前缀和 令A集合的前缀和为SA, ...
- 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 ...
- 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_ ...
- CodeForces - 618F Double Knapsack
Discription You are given two multisets A and B. Each multiset has exactly n integers each between 1 ...
- 618F Double Knapsack
传送门 题目大意 分析 代码 #include<iostream> #include<cstdio> #include<cstring> #include<s ...
- [codeforces 618 F] Double Knapsack (抽屉原理)
题目链接:http://codeforces.com/contest/618/problem/F 题目: 题目大意: 有两个大小为 N 的可重集 A, B, 每个元素都在 1 到 N 之间. 分别找出 ...
- BigDecimalAvoidDoubleConstructorRule:不要直接用double变量作为构造BigDecimal的参数
先上结论: 不要直接用double变量作为构造BigDecimal的参数. 线上有这么一段Java代码逻辑: 1,接口传来一个JSON串,里面有个数字:57.3. 2,解析JSON并把这个数字保存在一 ...
随机推荐
- UITableView 的横向滑动实现
UITableView 的横向滑动实现 概述 为了实现横向滑动的控件,可以继承类 UIScrollView 或类 UIView 自定义可以横向滑动的控件,这里通过 UITableView 的旋转,实现 ...
- 初次使用beego框架
安装beego框架以及bee工具 go get -u github.com/astaxie/beego go get github.com/beego/bee 创建一个新项目 bee new weba ...
- 【学习总结】Git学习-参考廖雪峰老师教程二-安装Git
学习总结之Git学习-总 目录: 一.Git简介 二.安装Git 三.创建版本库 四.时光机穿梭 五.远程仓库 六.分支管理 七.标签管理 八.使用GitHub 九.使用码云 十.自定义Git 期末总 ...
- windows下linux子系统安装
1.打开Windows功能中的使用于linux的Windows子系统 2.应用商店中下载需要的linux 3.下载完成后运行等待安装并输入用户名密码 4.查看系统信息 先后 sudo apt-get ...
- 开发工具之Sublime编辑器
sublime是一款轻量级的编辑器,可以从官网上进行下载最新版本.它有很多使用并且强大的功能支持.例如:GOTO,package 等快捷操作.但有时候下载的版本不能进行安装package contro ...
- [转帖]2015年时微软Win3.1崩溃迫使巴黎奥利机场短暂关闭
https://www.ithome.com/html/it/188796.htm IT之家讯 2015年11月14日消息,上周法国巴黎奥利机场因为微软的Windows 3.1系统出现故障不得不迫使所 ...
- 【学亮IT手记】使用Map代替switch...case语句
- 【Java基础】for循环实现在控制台打印水仙花数
代码: /* * 需求:在控制台输出所有的”水仙花数” * * 分析: * 什么是水仙花数呢? * 所谓的水仙花数是指一个三位数,其各位数字的立方和等于该数本身. * 举例:153就是一个水仙花数. ...
- JavaScript lastIndexOf() 方法
<script type="text/javascript"> var str="0000.0000.0000.0000.0000.0000.0000.&qu ...
- ELK日志系统+x-pack安全验证
根据之前已经搭好的ELK系统,现在加一个x-pack插件上去,不然谁拿到ip和端口都可以访问elasticsearch和kibana. 要的效果如下:打开kibana界面的时候要让其输入用户名密码才能 ...