Description

给出 \(n\) 个 \(\leq m\) 且不同的数 \(a_1,\dots,a_n\),现在要求从这 \(n\) 个数中选出最少的数字,满足这 \(n\) 个数字都可以由选出的数字组合成(就是做一个完全背包能做出来),并且任意组合出来的数字,只要不超过 \(m\),就必须让这个数字在给出的 \(n\) 个数中。问是否可行,如果可行,请求出最少选多少数字。 \(n,m\leq 10^6\)。

Sol

先判断是否可行,再看哪些数可以省略。

求出 \(a\) 数组的生成函数,即构造多项式 \(F(x)=\sum f_i\cdot x^i\)。\(f_i\) 为 \(1\) 当且仅当 \(a\) 数组中出现 \(a_*=i\)

然后求出 \(G(x)=F^2(i)=\sum g_i\cdot x^i\)。如果 \(g_i>0\) 那就说明给出的这 \(n\) 个数可以合成 \(i\) 。

于是就得到了从原来的 \(n\) 个数中拿出 \(0\sim 2\) 个的结果。

然而最多拿出 \(m\) 个。

所以还要继续,用快速幂求得 \(f^m\)。如果多项式快速幂的话,复杂度 \(O(n\log^2n)\),用多项式ln+多项式exp求的话,复杂度 \(O(n\log n)\)。但是多项式exp常数太大了!

事实上是有只做 \(1\) 次FFT的方法的。

显然如果 \(f_i>0\) 的话,\(g_i>0\)。

那我们只要保证满足 \(f_i=0,g_i>0,i\leq m\) 的 \(i\) 不存在就好了。

如果第一轮不存在这些不合法的,那接下来肯定也不存在。感性理解一下这就相当于构成了一个封闭的集合。

所以只做 \(1\) 次FFT就行了。

然后考虑一下哪些数可以省略

如果一个数 \(i\) 可以被其他数表示出来,那 \(g_i\) 一定 \(>2\)。所以 \(g_i=2\) 的 \(i\) 就是必选的。

时间复杂度 \(O(n\log n)\)。

Sol

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using std::min;
using std::max;
using std::swap;
using std::vector;
typedef double db;
typedef long long ll;
#define pb(A) push_back(A)
#define pii std::pair<int,int>
#define all(A) A.begin(),A.end()
#define mp(A,B) std::make_pair(A,B)
const int N=4e6+5;
const int mod=998244353; int lim,rev[N];
int n,m,a[N],b[N]; int ksm(int a,int b=mod-2,int ans=1){
while(b){
if(b&1) ans=1ll*ans*a%mod;
a=1ll*a*a%mod;b>>=1;
} return ans;
} int getint(){
int X=0,w=0;char ch=getchar();
while(!isdigit(ch))w|=ch=='-',ch=getchar();
while( isdigit(ch))X=X*10+ch-48,ch=getchar();
if(w) return -X;return X;
} void ntt(int *f,int g){
for(int i=1;i<lim;i++) if(i<rev[i]) swap(f[i],f[rev[i]]);
for(int mid=1;mid<lim;mid<<=1){
int tmp=ksm(g,(mod-1)/(mid<<1));
for(int R=mid<<1,j=0;j<lim;j+=R){
int w=1;
for(int k=0;k<mid;k++,w=1ll*w*tmp%mod){
int x=f[j+k],y=1ll*w*f[j+k+mid]%mod;
f[j+k]=(x+y)%mod,f[j+k+mid]=(mod+x-y)%mod;
}
}
} if(g>3)
for(int in=ksm(lim),i=0;i<lim;i++) f[i]=1ll*f[i]*in%mod;
} signed main(){
n=getint(),m=getint();
for(int i=1;i<=n;i++){
int x=getint();
a[x]=b[x]=1;
}
lim=1;while(lim<=m+m) lim<<=1;
for(int i=1;i<lim;i++) rev[i]=(rev[i>>1]>>1)|(i&1?lim>>1:0);
a[0]=1; ntt(a,3);
for(int i=0;i<lim;i++) a[i]=1ll*a[i]*a[i]%mod;
ntt(a,(mod+1)/3);
for(int i=1;i<=m;i++)
if(a[i] and !b[i]) return printf("NO"),0;
puts("YES"); int tot=0;
for(int i=1;i<=m;i++)
if(a[i]==2) tot++;
printf("%d\n",tot);
for(int i=1;i<=m;i++)
if(a[i]==2) printf("%d ",i);
return 0;
}

[CF286E] Ladies' shop的更多相关文章

  1. CF286E Ladies' Shop FFT

    题目链接 读完题后,我们发现如下性质: 在合法且和不超过 $m$ 的情况下,如果 $a_{i}$ 出现,则 $a_{i}$ 的倍数也必出现. 所以如果合法,只要对所有数两两结合一次就能得到所有 $a_ ...

  2. codeforces 286 E. Ladies' Shop (FFT)

    E. Ladies' Shop time limit per test 8 seconds memory limit per test 256 megabytes input standard inp ...

  3. codeforces 286E Ladies' Shop

    题目大意:n个小于等于m的数,现在你需要在[1,m]中选择若干个数,使得选出的数能组成的所有数正好与n个数相同,给出最少要选多少个数. 题目分析: 结论一:选择的若干个数一定在n个数中. 证明:否则的 ...

  4. CodeForces 286E Ladies' Shop 多项式 FFT

    原文链接http://www.cnblogs.com/zhouzhendong/p/8781889.html 题目传送门 - CodeForces 286E 题意 首先,给你$n$个数(并告诉你$m$ ...

  5. Ladies' Shop

    题意: 有 $n$ 个包,设计最少的物品体积(可重集),使得 1. 对于任意一个总体积不超过给定 $m$ 的物体集合有其体积和 恰好等于一个包的容量. 2.对于每一个包,存在一个物品集合能恰好装满它. ...

  6. Codeforces 286E - Ladies' Shop(FFT)

    Codeforces 题面传送门 & 洛谷题面传送门 好久没刷过 FFT/NTT 的题了,写篇题解罢( 首先考虑什么样的集合 \(T\) 符合条件.我们考察一个 \(x\in S\),根据题意 ...

  7. 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】

    原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...

  8. Codeforces Round #176 (Div. 1 + Div. 2)

    A. IQ Test 模拟. B. Pipeline 贪心. C. Lucky Permutation 每4个数构成一个循环. 当n为偶数时,n=4k有解:当n为奇数时,n=4k+1有解. D. Sh ...

  9. codeforces 632+ E. Thief in a Shop

    E. Thief in a Shop time limit per test 5 seconds memory limit per test 512 megabytes input standard ...

随机推荐

  1. CentOS 6下升级Python版本

    CentOS6.8默认的python版本是2.6,而现在好多python组件开始只支持2.7以上的版本,比如说我今天遇到的pip install pysqlite,升级python版本是一个痛苦但又常 ...

  2. 学习python一个月盘点

    1,看了30多个视频,是一些基本操作的.粗略的了解了语法,函数,循环,正则表达,将视频内容全部敲入文本: 2,看了100页的书,习题不太会,进展很慢.第五章10以后的题都没做: 3,看C++的书,有点 ...

  3. 个人 WPF+EF(DBFirst) 简单应用开发习惯及EF学习测试(备忘) -- 2

    接上篇:个人 WPF+EF(DBFirst) 简单应用开发习惯及EF学习测试(备忘) -- 1 Step1 在主程序中设置连接数据库 从Model类库的 App.Config 把数据库字符串拷贝出来, ...

  4. 大众点评selfxss结合两个csrf变废为宝(已修复,故公开,不涉及真实参数)

    大众点评selfxss结合两个csrf变废为宝 漏洞不值钱,但还是蛮好玩的 漏洞信息 类型:存储型xss 场景:收藏商户后,去已收藏的商户列表可以给指定商户添加tag(与下文html标签区别) 漏洞限 ...

  5. Linux上搭建Hadoop集群

    本文将为初学者的搭建简单的伪分布式集群,将搭建一台虚拟机,用于学习Hadoop 工具:vm虚拟机,centOS7,jdk-8,Hadoop2.7,xftp,xshell 用户:在虚拟机中创建一个had ...

  6. 关于Android 8.0java.lang.SecurityException: Permission Denial错误的解决方法

    背景 当我在Android 7.0及以下手机运行启动页,进行Activity跳转的时候,完美跳转到对应的目标Activity. 但当在Android 8.0及以上手机进行Activity跳转时,会爆如 ...

  7. IO在Socket中的应用

    一.BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要对每个连接 ...

  8. Firewalld的结构

    原文地址:http://www.excelib.com/article/287/show firewalld简介 Centos7中默认将原来的防火墙iptables升级为了firewalld,fire ...

  9. tcpdump完全指南

    先从第一个最简单的抓包指令开始 抓经过本主机上的所有网络接口的所有ARP.ICMP.IGMP.IP.TCP.UDP等所有网络包(以下简称“所有网络包”) tcpdump -i any -vnn (注: ...

  10. html5之上的图片处理

    在开发 H5 应用的时候碰到一个问题,应用只需要一张小的缩略图,而用户用手机上传的确是一张大图,手机摄像机拍的图片好几 M,这可要浪费很多流量. 像我这么为用户着想的程序员,绝对不会让这种事情发生的, ...