CodeForces 286E Ladies' Shop 多项式 FFT
原文链接http://www.cnblogs.com/zhouzhendong/p/8781889.html
题目传送门 - CodeForces 286E
题意
首先,给你$n$个数(并告诉你$m$),分别为$p_{1\dots n}$。
让你求一个数的集合,满足:
当且仅当从这个数的集合中取数(可以重复)求和时(设得到的和为$sum$),如果$sum\leq m$,则数$sum$在给你的$n$个数之中。
如果没有这种集合,输出$NO$。
否则,先输出$YES$,然后输出这个集合最小时的元素个数,并输出集合中的所有元素。
$1\leq n,m\leq 10^6,1\leq p_i\leq 10^6$
题解
大大的标签里面写着$FFT$。
然而我只会$O(m \log^2 m)$。QAQ
瞅了眼题解。发现我果然是大菜鸡。
好了开始讲算法。
首先,我们构造一个多项式:
$$f=1x^0+a_1x^1+a_2x^2+\dots+a_ix^i+\dots+a_{m-1}x^{m-1}+a_mx^m$$
其中,如果数$i$在告诉你的$n$个数中出现过,那么$a_i=1$,否则$a_i=0$。
然后我们$FFT$求得$f^2$。
有什么用??
当然有用。(这大概是个比较好的套路)
设$f^2$的$i$次项系数为$b_i$,那么,如果$b_i>0$则可以通过给你的$n$个数来合成$i$。
那为什么我们先要让给你的$n$个数的$a_i$都变成$1$呢,显然给你的$n$个数一定会被合成,也一定会被用于合成其他的数。
那为什么$a_0=1$呢?显然一个数加上$0$是不变的,弄个$0$上去可以保留原来有的$n$个数。
于是你得到了从原来的$n$个数中拿出$0$~$2$个的结果。
然而最多可能拿$m$个。
所以你还要继续,用快速幂求得$f^m$。
时间复杂度$O(m\log^2 m)$。
事实上我傻掉了。
显然$a_i>0$的,$b_i$也$>0$,由于$0$的存在。
那么我们只要保证$a_i=0,b_i>0,i\leq m$的不存在就好了。
如果第一轮不存在这些不合法的。
那么显然后面也不可能。因为系数不为$0$的仍然是那些原来的$i$。
于是只要一次$FFT$。
然后考虑一下哪些数可以省略。
显然,结果中$b_i$有两次贡献是$0$与$a_i$做的,如果$b_i$大于$2$说明$i$可以通过其他的两个数相加得到,所以$i$可以不在结果的集合里。反之,如果$b_i=2$,那么显然一定在结果的集合里面。
然后就放代码了。注意我代码里面的$n$的意义不是输入的$n$。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=1<<21;
double PI=acos(-1.0);
int read(){
int x=0;
char ch=getchar();
while (!('0'<=ch&&ch<='9'))
ch=getchar();
while ('0'<=ch&&ch<='9')
x=(x<<1)+(x<<3)+ch-48,ch=getchar();
return x;
}
int nn,m,a[N],b[N];
int n,L,R[N];
struct C{
double r,i;
C(){}
C(double a,double b){r=a,i=b;}
C operator + (C x){return C(r+x.r,i+x.i);}
C operator - (C x){return C(r-x.r,i-x.i);}
C operator * (C x){return C(r*x.r-i*x.i,r*x.i+i*x.r);}
}A[N],B[N],CC[N],w[N];
double x[N],y[N],z[N];
void FFT(C a[]){
for (int i=0;i<n;i++)
if (i>R[i])
swap(a[i],a[R[i]]);
for (int t=n>>1,d=1;d<n;d<<=1,t>>=1)
for (int i=0;i<n;i+=(d<<1))
for (int j=0;j<d;j++){
C tmp=w[t*j]*a[i+j+d];
a[i+j+d]=a[i+j]-tmp;
a[i+j]=a[i+j]+tmp;
}
}
void FFT_times(double x[],double y[],double z[]){
for (int i=0;i<n;i++)
A[i]=C(x[i],0),B[i]=C(y[i],0);
FFT(A),FFT(B);
for (int i=0;i<n;i++)
CC[i]=A[i]*B[i],w[i].i*=-1.0;
FFT(CC);
for (int i=0;i<n;i++)
z[i]=CC[i].r/n,w[i].i*=-1.0;
}
int main(){
nn=read(),m=read();
memset(a,0,sizeof a);
a[0]=1;
for (int i=1,x;i<=nn;i++)
a[read()]=1;
for (n=1,L=0;n<(m+1)*2;n<<=1,L++);
for (int i=0;i<n;i++){
R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
w[i]=C(cos(2*i*PI/n),sin(2*i*PI/n));
}
for (int i=0;i<n;i++)
x[i]=y[i]=i<=m?a[i]:0;
FFT_times(x,y,z);
for (int i=1;i<=m;i++)
b[i]=(int)(z[i]+0.5);
int flag=0;
for (int i=1;i<=m;i++)
if (!a[i]&&b[i]){
flag=-1;
break;
}
else if (a[i]&&b[i]==2)
flag++;
if (flag==-1)
puts("NO");
else {
puts("YES");
printf("%d\n",flag);
for (int i=1;i<=m;i++)
if (a[i]&&b[i]==2)
printf("%d ",i);
}
return 0;
}
CodeForces 286E Ladies' Shop 多项式 FFT的更多相关文章
- Codeforces 286E - Ladies' Shop(FFT)
Codeforces 题面传送门 & 洛谷题面传送门 好久没刷过 FFT/NTT 的题了,写篇题解罢( 首先考虑什么样的集合 \(T\) 符合条件.我们考察一个 \(x\in S\),根据题意 ...
- codeforces 286E Ladies' Shop
题目大意:n个小于等于m的数,现在你需要在[1,m]中选择若干个数,使得选出的数能组成的所有数正好与n个数相同,给出最少要选多少个数. 题目分析: 结论一:选择的若干个数一定在n个数中. 证明:否则的 ...
- 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 528D Fuzzy Search 多项式 FFT
原文链接http://www.cnblogs.com/zhouzhendong/p/8782849.html 题目传送门 - CodeForces 528D 题意 给你两个串$A,B(|A|\geq| ...
- Educational Codeforces Round 9 E. Thief in a Shop dp fft
E. Thief in a Shop 题目连接: http://www.codeforces.com/contest/632/problem/E Description A thief made hi ...
- CodeForces 958F3 Lightsabers (hard) 启发式合并/分治 多项式 FFT
原文链接http://www.cnblogs.com/zhouzhendong/p/8835443.html 题目传送门 - CodeForces 958F3 题意 有$n$个球,球有$m$种颜色,分 ...
- CodeForces 623E Transforming Sequence 动态规划 倍增 多项式 FFT 组合数学
原文链接http://www.cnblogs.com/zhouzhendong/p/8848990.html 题目传送门 - CodeForces 623E 题意 给定$n,k$. 让你构造序列$a( ...
- Codeforces 438E. The Child and Binary Tree 多项式,FFT
原文链接www.cnblogs.com/zhouzhendong/p/CF438E.html 前言 没做过多项式题,来一道入门题试试刀. 题解 设 $a_i$ 表示节点权值和为 $i$ 的二叉树个数, ...
- CodeForces 553E Kyoya and Train 动态规划 多项式 FFT 分治
原文链接http://www.cnblogs.com/zhouzhendong/p/8847145.html 题目传送门 - CodeForces 553E 题意 一个有$n$个节点$m$条边的有向图 ...
随机推荐
- maven在windows及linux环境下安装
maven下载 下载地址:https://maven.apache.org/download.cgi maven在windows下安装 解压到D盘 修改配置文件 进入conf,打开settings.x ...
- 《从Paxos到ZooKeeper分布式一致性原理与实践》学习笔记
第一章 分布式架构 1.1 从集中式到分布式 集中式的特点: 部署结构简单(因为基于底层性能卓越的大型主机,不需考虑对服务多个节点的部署,也就不用考虑多个节点之间分布式协调问题) 分布式系统是一个硬件 ...
- 【Sql Server】SQL SERVER 收缩日志
事务日志记录着在相关数据库上的操作,同时还存储数据库恢复(recovery)的相关信息. 收缩日志的原因有很多种,有些是考虑空间不足,有些则是应用程序限制导致的. 下面介绍的是在简单模式下,进行收缩操 ...
- Matlab怎么修改显示数值格式/精度/小数位数
参考:https://jingyan.baidu.com/article/7f41ecec1ad029593c095c70.html
- 第十五节:HttpContext五大核心对象的使用(Request、Response、Application、Server、Session)
一. 基本认识 1. 简介:HttpContext用于保持单个用户.单个请求的数据,并且数据只在该请求期间保持: 也可以用于保持需要在不同的HttpModules和HttpHandlers之间传递的值 ...
- /etc/profile文件被改坏导致命令不可用
这几天在装一个软件,设置环境变量的时候,不小心把/etc/profile文件改坏了(就是没配置对),在source /etc/profile后导致所有命令都不可用了.出现如下报错: -bash: xx ...
- [译]Ocelot - Getting Started
原文 Ocelot专为.NET Core而设计. .NET Core 2.1 安装 首先需要创建一个netstandard2.0项目,然后再通过nuget安装. Install-Package Oce ...
- Shpinx在PHPCMS里的使用及配置
现在可以用最新版的Sphinx版本 网址:http://sphinxsearch.com/downloads/release/ 我使用rpm方式: 下载RHEL/CentOS 6.x x86_64 R ...
- C# - 设计模式 - 策略模式
策略模式 问题场景 多个类型都有一些共同的属性和方法,可以称这些成员为行为,为了避免重复在多个类型中编码相同部分的行为,应考虑将这些行为定义在抽象类(超类)中,利用继承时多个类型可以共享这些行为.比如 ...
- vim简单使用教程【转】
vim的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类,你一定会对这个编辑器失去兴趣的.下面的文章翻译自<Learn Vim Progress ...