[CF286E] Ladies' shop
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的更多相关文章
- CF286E Ladies' Shop FFT
题目链接 读完题后,我们发现如下性质: 在合法且和不超过 $m$ 的情况下,如果 $a_{i}$ 出现,则 $a_{i}$ 的倍数也必出现. 所以如果合法,只要对所有数两两结合一次就能得到所有 $a_ ...
- codeforces 286 E. Ladies' Shop (FFT)
E. Ladies' Shop time limit per test 8 seconds memory limit per test 256 megabytes input standard inp ...
- codeforces 286E Ladies' Shop
题目大意:n个小于等于m的数,现在你需要在[1,m]中选择若干个数,使得选出的数能组成的所有数正好与n个数相同,给出最少要选多少个数. 题目分析: 结论一:选择的若干个数一定在n个数中. 证明:否则的 ...
- CodeForces 286E Ladies' Shop 多项式 FFT
原文链接http://www.cnblogs.com/zhouzhendong/p/8781889.html 题目传送门 - CodeForces 286E 题意 首先,给你$n$个数(并告诉你$m$ ...
- Ladies' Shop
题意: 有 $n$ 个包,设计最少的物品体积(可重集),使得 1. 对于任意一个总体积不超过给定 $m$ 的物体集合有其体积和 恰好等于一个包的容量. 2.对于每一个包,存在一个物品集合能恰好装满它. ...
- Codeforces 286E - Ladies' Shop(FFT)
Codeforces 题面传送门 & 洛谷题面传送门 好久没刷过 FFT/NTT 的题了,写篇题解罢( 首先考虑什么样的集合 \(T\) 符合条件.我们考察一个 \(x\in S\),根据题意 ...
- 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】
原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...
- 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 ...
- 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 ...
随机推荐
- abaqus修改inp直接建立工程
前面已经知道,通过修改以下inp的节点和单元编号,就可以新建模型,可是对于大的工程来说,逐个选取单元进行添加材料以及确定哪步进行填土仍是比较麻烦的(如果工程网格划分好并告知哪些单元好属于哪些材料,哪些 ...
- mvc 路由伪静态实现
很多网站都采用伪静态,例如以html.shtml等结尾的url,mvc的路由可以轻松实现. 配置路由 默认路由配置 添加伪静态路由 mvc的路由原理是从上往下匹配的,所以只需要在后面添加自己配置的路由 ...
- centos7安装mariadb
~]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) 1.官方um安装mariadb 1).准备官方yum [mariadb ...
- 功能强大的js数组方法:reduce
arr.reduce()方法接受一个函数作为累加器,数组中的每个值从左到右开始缩减,最终为一个值. reduce接受的参数主要有callback(回调函数)和可选参数initvalue(作为第一次调用 ...
- mac上terminal_问题_1117
(1)安装Homebrew /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install ...
- Vipe框架构思记
准备着手写一个JAVA框架,基于公司目前的框架提取出来.当然公司现在的框架也是我搭建的.在这整理一下思路. 框架名称:Vipe AOP,IOC容器:Spring MVC:Spring MVC ORM: ...
- jenkins:一个jenkins项目远程触发另一个jenkins项目构建配置
很多时候,我们会有这样的应用场景:一个jenkins上的项目构建后,需要远程触发另一台机子上的jenkins中某个项目的构建,可以通过Parameterized Remote Trigger Conf ...
- 技术干货:实时视频直播首屏耗时400ms内的优化实践
本文由“逆流的鱼yuiop”原创分享于“何俊林”公众号,感谢作者的无私分享. 1.引言 直播行业的竞争越来越激烈,进过2018年这波洗牌后,已经度过了蛮荒暴力期,剩下的都是在不断追求体验.最近正好在做 ...
- 网络编程懒人入门(六):深入浅出,全面理解HTTP协议
本文引用了自简书作者“涤生_Woo”的文章,内容有删减,感谢原作者的分享. 1.前言 HTTP(全称超文本传输协议,英文全称HyperText Transfer Protocol)是互联网上应用最为广 ...
- Windows下编译安装 FFmpeg
在Linux/Mac下编译 ffmpeg是非常方便的.但要在 Windows下编译 ffmpeg还真要花点时间.以下就是在 Windowns下编译ffmpeg的步骤: 一.安装Cygwin 在wind ...