题目链接:http://codeforces.com/contest/618/problem/F

题目:

题目大意:

有两个大小为 N 的可重集 A, B, 每个元素都在 1 到 N 之间. 分别找出 A 和 B 的一个子集, 使得这两个子集元素之和相等.

分别输出集合A和集合B的子集的个数以及子集中元素在原集合中的位置

N ≤ $10^6$

题解:

首先我们证明一个结论,存在一组方案,满足两个子集在A中和在B中都是连续的一段

把两个集合看成两个数组,分别计算出前缀和sa,sb

对于每个i(0<=i<=n),我们j为满足0<=sa[i]-sb[j]<=n-1的最大的j,设d[i]=sa[i]-sb[j],可以发现j的单调递增的

我们发现d数组一共有n+1个元素(包括i=0,sa[i]=0的情况),并且我们又发现d[i]的取值只有n个。那么根据抽屉原理,至少有两个d数组中的元素是相等的

于是我们有sa[i']-sb[j']=sa[i]-sb[j](i'>i)

移项之后得到sa[i']-sa[i]=sb[j']-sb[j]

这个时候我们就知道在A数组中i+1~i'这一段元素之和与B数组中j+1~j'这一段元素之和相等

证毕

其实上面的证明过程就是我们本题的做法,我们用two pointers处理出d数组,然后判断当前的d值在之前是否出现过,这个时候我们就得到了答案

值得注意的是,我们需要sa[n]<=sb[n],因为若是sa[n]>sb[n]可能出现对于i=n找不到一个j满足上述条件

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std; const int N=1e6+;
int n,cnt1,cnt2,st1,st2,ed1,ed2;
int sa[N],sb[N],vis[N],p[N];
inline int read()
{
char ch=getchar();
int s=,f=;
while (ch<''||ch>'') {if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=getchar();}
return s*f;
}
void solve(int a[],int b[])
{
memset(vis,-,sizeof(vis));
int j=;
for (int i=;i<=n;i++)
{
while (a[i]-b[j]>=n) j++;
int d=a[i]-b[j];
if (vis[d]!=-)
{
cnt1=i-vis[d];
st1=vis[d]+;ed1=i;
cnt2=j-p[vis[d]];
st2=p[vis[d]]+;ed2=j;
break;
}
vis[d]=i;p[i]=j;
}
}
int main()
{
n=read();
for (int i=;i<=n;i++) sa[i]=sa[i-]+read();
for (int i=;i<=n;i++) sb[i]=sb[i-]+read();
if (sa[n]<=sb[n])
{
solve(sa,sb);
}
else
{
solve(sb,sa);swap(cnt1,cnt2);swap(st1,st2);swap(ed1,ed2);
}
printf("%d\n",cnt1);
for (int i=st1;i<=ed1;i++) printf("%d ",i);
printf("\n");
printf("%d\n",cnt2);
for (int i=st2;i<=ed2;i++) printf("%d ",i);
printf("\n");
return ;
}

[codeforces 618 F] Double Knapsack (抽屉原理)的更多相关文章

  1. 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 ...

  2. CF618F Double Knapsack 构造、抽屉原理

    传送门 首先,选取子集的限制太宽了,子集似乎只能枚举,不是很好做.考虑加强限制条件:将"选取子集"的限制变为"选取子序列"的限制.在接下来的讨论中我们将会知道: ...

  3. 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_ ...

  4. CodeForces 485A Factory (抽屉原理)

    A. Factory time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  5. Codeforces Round #319 (Div. 2) B. Modulo Sum 抽屉原理+01背包

    B. Modulo Sum time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  6. Codeforces 958C3 - Encryption (hard) 区间dp+抽屉原理

    转自:http://www.cnblogs.com/widsom/p/8863005.html 题目大意: 比起Encryption 中级版,把n的范围扩大到 500000,k,p范围都在100以内, ...

  7. 51nod 1103 N的倍数(抽屉原理)

    1103 N的倍数 题目来源: Ural 1302 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 一个长度为N的数组A,从A中选出若干个数,使得这些数的和是N的倍 ...

  8. 【CF618F】Double Knapsack(构造)

    [CF618F]Double Knapsack(构造) 题面 洛谷 Codeforces 题解 很妙的一道题. 发现找两个数集很不爽,我们强制加强限制,我们来找两个区间,使得他们的区间和相等. 把区间 ...

  9. bzoj#4722-由乃【倍增,抽屉原理,bitset】

    正题 题目链接:https://darkbzoj.tk/problem/4722 题目大意 给出一个长度为\(n\)的序列值域为\([0,v)\),要求支持操作 询问一个区间能否找到两个没有交的非空下 ...

随机推荐

  1. leetcode笔记:Find Median from Data Stream

    一. 题目描写叙述 Median is the middle value in an ordered integer list. If the size of the list is even, th ...

  2. IOS版本号被拒的经历

    IOS版本号被拒的经历: 1,登陆方式依赖外部平台 由于我们的APP是仅仅用微博登陆.想做成类似meerkat类型的.也能各种消息都同步微博. 结果当然行不通,这个确实是不听好人言.网上多个人都说过这 ...

  3. spring web mvc第一天

    spring  web mvc 感觉就是高大上啊!啥都是配置文件就能够了.所以第一步就是弄清楚配置文件使用和总体框架的流程! Spring web mvc最重要的当然是Controller,也就是首先 ...

  4. Ruby学习笔记(一)

    在做实验的时候,由于每次都要手工修改文件夹的名字,实在是给自己添了太多的麻烦,为了摆脱手工修改的困恼,于是产生了一个使用程序批量修改文件夹名字的好主意.为了最终实现这个目标,自然需要选择一种合适的脚本 ...

  5. 智课雅思词汇---十二、vent是什么意思

    智课雅思词汇---十二.vent是什么意思 一.总结 一句话总结:词根:ven, vent = come, 表示“来” 词根:vent = wind 风 1.tact是什么意思? 词根:-tact-, ...

  6. vue-cli全引入jquery

    欢迎加入前端交流群交流知识&&获取视频资料:749539640 vue-cli全引入jquery:(vue-cli使用webpack) 第一步: 在package.json文件里的de ...

  7. Java 以空格分割字符串

    Java中使用类似于 str.split("/"); 的方法可以很方便的实现将一个字符串分割为数组, 但是如果分隔符是一个(或几个)空格呢?? 我们的本能反应或许应该是 str.s ...

  8. Page Layout里的javascript (jquery)不执行

    在page layout 中通过 _spBodyOnLoadFunctionNames.push("js 方法名") 的方式实现. 但切记,代码要放到 PlaceHolderMai ...

  9. kinEditor动态渲染的问题

    摘自:jingyan.baidu.com/article/a65957f4a4c89a24e67f9b3d.html 在使用kindEditor时,因为textarea是动态加载的,因而对textar ...

  10. asp.net HTTP请求过程

    http://blog.csdn.net/zxxSsdsd/article/details/51909860