codeforces 286 E. Ladies' Shop (FFT)
8 seconds
256 megabytes
standard input
standard output
A ladies' shop has recently opened in the city of Ultima Thule. To get ready for the opening, the shop bought n bags. Each bag is characterised by the total weight ai of the items you can put there. The weird thing is, you cannot use these bags to put a set of items with the total weight strictly less than ai. However the weights of the items that will be sold in the shop haven't yet been defined. That's what you should determine right now.
Your task is to find the set of the items' weights p1, p2, ..., pk (1 ≤ p1 < p2 < ... < pk), such that:
- Any bag will be used. That is, for any i (1 ≤ i ≤ n) there will be such set of items that their total weight will equal ai. We assume that there is the infinite number of items of any weight. You can put multiple items of the same weight in one bag.
- For any set of items that have total weight less than or equal to m, there is a bag into which you can put this set. Similarly, a set of items can contain multiple items of the same weight.
- Of all sets of the items' weights that satisfy points 1 and 2, find the set with the minimum number of weights. In other words, value k should be as small as possible.
Find and print the required set.
The first line contains space-separated integers n and m (1 ≤ n, m ≤ 106). The second line contains ndistinct space-separated integers a1, a2, ..., an (1 ≤ a1 < a2 < ... < an ≤ m) — the bags' weight limits.
In the first line print "NO" (without the quotes) if there isn't set pi, that would meet the conditions.
Otherwise, in the first line print "YES" (without the quotes), in the second line print an integer k (showing how many numbers are in the suitable set with the minimum number of weights), in the third line print kspace-separated integers p1, p2, ..., pk (1 ≤ p1 < p2 < ... < pk). If there are multiple solutions, print any of them.
6 10
5 6 7 8 9 10
YES
5
5 6 7 8 9
1 10
1
NO
1 10
6
YES
1
6
——————————————————————————
然后来谈谈这道题了
题面是给n个篮子,要求制造不限制数目的商品,要求这些商品任意组合(可重复)的和在<m时总能找到一个容量等于和的篮子
有解输出YES,个数,商品的值,多组解要求输出篮子数最少,没有输出NO
首先按照题意来说我们随便组合这些商品,获得的值都有一个篮子来装
那么如果我们按每个篮子的值制造一种商品,每个篮子的值都可以由一个原商品,或两个原商品得到
为什么不是三个或以上,建设是三个组成这个篮子值A的话其中两个组成的商品会有一个篮子B来装,按照我们的条件,这个篮子值B的商品已经被制造出来了,所以假设不成立
也就是这样——
(栗子)
n=3 m=3
篮子:1 2 3
我们制造出的商品:1 2 3
我们发现1 1 1可以填满容量为3的篮子
但是1 1组合是2 ,我们已经制造出了2
可以是3=1+2,当然也有3=3
这个说明我们只要这样制造商品,每个商品和所有商品(包括自身)重新组合,就可以得到所有m以内商品和的种类 ——
(例子)
n=3 m=6(修改m)
篮子:1 2 3
我们制造出的商品:1 2 3
可搭配出
1+1=2 1+2=3 1+3=4
2+1=3 2+2=4 2+3=5
3+1=4 3+2=5 3+3=6
我们通过这些值可以判断,创造出的4 5 6无法装下,所以是NO
如果m=3
n=3 m=3
篮子:1 2 3
我们制造出的商品:1 2 3
可搭配出
1+1=2 1+2=3 1+3=4
2+1=3 2+2=4 2+3=5
3+1=4 3+2=5 3+3=6
我们发现2 3能被重新组合出来所以我们贪心地删除2 3 答案就是1
2用来构建3的,怎么被删除了呢
如果2被删除,说明2也可以被构建,故删除
所以根据xa*xb=xa+b
我们可以根据(xa1*xa2...xan)2来判断两两组合的所有解,满足卷积,所以FFT
【两个版本的FFT↓】
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstring>
#define siji(i,x,y) for(int i=(x);i<=(y);++i)
#define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
#define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
#define sigongzi(j,x,y) for(int j=(x);j>(y);--j)
typedef long long ll;
const double PI=3.14159265358979323;//似乎精度要大大大大大大大
using namespace std;
struct complex {
double r,i;
complex(double real=0.0,double image=0.0) {
r=real;i=image;
}
complex operator + (const complex &a)const {
return complex(r+a.r,i+a.i);
}
complex operator - (const complex &a)const {
return complex(r-a.r,i-a.i);
}
complex operator * (const complex &a) const{
return complex(r*a.r-i*a.i,r*a.i+i*a.r);
}
}num1[],num2[];
void brc(complex *p,int l) {
int j=l/;
for(int i=;i<l-;++i) {//l-1是因为如果最后减完k=0,j=0
if(i<j) swap(p[i],p[j]);
int k=l/;
while(j>=k) {
j-=k;
k>>=;
}
if(j<k) j+=k;
}
}
//迭代版
void FFT(complex *p,int l,double flag) {
brc(p,l);
complex u,t;
for(int h=;h<=l;h<<=) {
complex wn(cos(flag**PI/h),sin(flag**PI/h));
for(int k=;k<l;k+=h){
complex w(,);
for(int j=k;j<k+h/;++j) {
u=p[j];
t=w*p[j+h/];
p[j]=u+t;
p[j+h/]=u-t;
w=w*wn;
}
}
}
}
//递归版
/*complex tmp[505];
void FFT(complex *p,int dep,int l,double flag) {
if((1<<dep)==l) return;
int step=1<<dep;
FFT(p,dep+1,l,flag);
FFT(p+step,dep+1,l,flag);
int newlen=l>>dep,half=newlen>>1;
complex wn(cos(2*flag*PI/newlen),sin(2*flag*PI/newlen));
complex w(1,0);
for(int i=0,s=0;i<half;++i,s+=(step<<1)) {
complex a=p[s];
complex b=w*p[s+step];
tmp[i]=a+b;
tmp[i+half]=a-b;
w=w*wn;
}
for(int i=0;i<newlen;++i) {
p[i<<dep]=tmp[i];
}
}//IDFT要除l*/
bool ok;
int a,b[],ans[],ac[],cnt;
int n,m;
void solve() {
scanf("%d%d",&n,&m);
int l=;
memset(b,,sizeof(b));
siji(i,,n) {
scanf("%d",&a);
b[a]=;
}
while(l<*m) {l=l<<;}
xiaosiji(i,,m) {
num1[i]=complex((double)b[i],0.0); }
FFT(num1,l,);
xiaosiji(i,,l) {
num2[i]=num1[i];
}
xiaosiji(i,,l) {
num1[i]=num1[i]*num2[i];
}
FFT(num1,l,-);
for(int z=;z<l;++z) num1[z].r/=l;
ok=true;
siji(i,,m) {
ans[i]=(int)(num1[i].r+0.5);
}
//为什么我这个sb写了个进位??????
//明明这不是大整数乘法啊QAQ
siji(i,,m) {
if(ans[i]>) {
if(b[i]==) {b[i]=;}
else if(b[i]==) {ok=;}
}
}
if(ok) {
puts("YES");
siji(i,,m) {
if(b[i]>) ac[++cnt]=i;
}
printf("%d\n",cnt);
siji(i,,cnt) {
printf("%d%c",ac[i]," \n"[i==cnt]);
}
}
else{
puts("NO");
}
}
int main(int argc, char const *argv[])
{
//freopen("f1.in","r",stdin);
solve();
return ;
}
codeforces 286 E. Ladies' Shop (FFT)的更多相关文章
- Codeforces 286E - Ladies' Shop(FFT)
Codeforces 题面传送门 & 洛谷题面传送门 好久没刷过 FFT/NTT 的题了,写篇题解罢( 首先考虑什么样的集合 \(T\) 符合条件.我们考察一个 \(x\in S\),根据题意 ...
- 快速傅里叶(FFT)的快速深度思考
关于按时间抽取快速傅里叶(FFT)的快速理论深度思考 对于FFT基本理论参考维基百科或百度百科. 首先谈谈FFT的快速何来?大家都知道FFT是对DFT的改进变换而来,那么它究竟怎样改进,它改进的思想在 ...
- 【BZOJ3527】力(FFT)
[BZOJ3527]力(FFT) 题面 Description 给出n个数qi,给出Fj的定义如下: \[Fj=\sum_{i<j}\frac{q_i q_j}{(i-j)^2 }-\sum_{ ...
- 【BZOJ4827】【HNOI2017】礼物(FFT)
[BZOJ4827][HNOI2017]礼物(FFT) 题面 Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一 个送给她.每 ...
- FFT/NTT总结+洛谷P3803 【模板】多项式乘法(FFT)(FFT/NTT)
前言 众所周知,这两个东西都是用来算多项式乘法的. 对于这种常人思维难以理解的东西,就少些理解,多背板子吧! 因此只总结一下思路和代码,什么概念和推式子就靠巨佬们吧 推荐自为风月马前卒巨佬的概念和定理 ...
- 【BZOJ4503】两个串(FFT)
[BZOJ4503]两个串(FFT) 题面 给定串\(S\),以及带通配符的串\(T\),询问\(T\)在\(S\)中出现了几次.并且输出对应的位置. \(|S|,|T|<=10^5\),字符集 ...
- 【BZOJ4259】残缺的字符串(FFT)
[BZOJ4259]残缺的字符串(FFT) 题面 给定两个字符串\(|S|,|T|\),两个字符串中都带有通配符. 回答\(T\)在\(S\)中出现的次数. \(|T|,|S|<=300000\ ...
- 【51Nod1258】序列求和V4(FFT)
[51Nod1258]序列求和V4(FFT) 题面 51Nod 多组数据,求: \[Ans=\sum_{i=1}^ni^k,n\le 10^{18},k\le50000\] 题解 预处理伯努利数,时间 ...
- 【CF528D】Fuzzy Search(FFT)
[CF528D]Fuzzy Search(FFT) 题面 给定两个只含有\(A,T,G,C\)的\(DNA\)序列 定义一个字符\(c\)可以被匹配为:它对齐的字符,在距离\(K\)以内,存在一个字符 ...
随机推荐
- LocalDateTime与字符串互转/Date互转/LocalDate互转/指定日期/时间比较
Java 8中表示日期和时间的类有多个,主要的有: Instant:表示时刻,不直接对应年月日信息,需要通过时区转换 LocalDateTime: 表示与时区无关的日期和时间信息,不直接对应时刻,需要 ...
- 《A First Course in Abstract Algebra with Applications》-chaper1-数论-棣莫弗定理
定理1.24 (棣莫弗定理) 对每个实数x和每个正整数n有 基于棣莫弗定理的推论如下:
- Packet Tracer 5.0实验(一) 交换机的Telnet远程登录设置
一.实验目标 掌握采用telnet方式配置交换机的方法 二.技术原理 配置交换机的管理IP地址(计算机的IP地址与交换机管理IP地址在同一网段): 为telnet用户配置用户名和登录口令: enabl ...
- NGINX生产环境反向代理到后端tomcat配置
#当访问www.kazihuo.com//sichuan-user-te时,跳转到http://10.1.93.61:7005/sichuan-user server { listen ; serve ...
- 判断android是否是debug
1.使用BuildConfig.DEBUG,这个在住modul里面是有效的,但是在有依赖库里面使用就会一直返回false,可以通过下面的方法解决:在library的build.gradle中添加以下代 ...
- Java并发编程原理与实战四十四:final域的内存语义
一.final域的重排序规则 对于final域,编译器和处理器要遵循两个重拍序规则: 1.在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序 ...
- .NET 定时器类及使用方法
Timer类实现定时任务 //2秒后开启该线程,然后每隔4s调用一次 System.Threading.Timer timer = new System.Threading.Timer((n) =&g ...
- [转]extern与头文件(*.h)的区别和联系
用#include可以包含其他头文件中变量.函数的声明,为什么还要extern关键字? 如果我想引用一个全局变量或函数a,我只要直接在源文件中包含#include<xxx.h> (xxx. ...
- 20155214 2016-2017-2 《Java程序设计》第7周学习总结
20155214 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 UTC时间以Unix元年(1970年)为起点经过的秒数. ISO 8601并非年历系统,大部 ...
- 【多视图几何】TUM 课程 第1章 数学基础:线性代数
在 YouTube 上找到了慕尼黑工业大学(Technische Universitaet München)计算机视觉组 Daniel Cremers 教授的 Multiple View Geomet ...