Codeforces 题面传送门 & 洛谷题面传送门

好久没刷过 FFT/NTT 的题了,写篇题解罢(

首先考虑什么样的集合 \(T\) 符合条件。我们考察一个 \(x\in S\),根据题意它能够表示成若干个 \(\in T\) 的数之和,这样一来我们可以分出两种情况,如果 \(x\) 本来就属于 \(T\),那么 \(x\) 自然就符合条件,这种情况我们暂且忽略不管。否则根据题设,必然存在一个数列 \(b_1,b_2,\cdots,b_m\),满足 \(m\ge 2,\forall i\in[1,m],b_i\in T\),且 \(\sum\limits_{i=1}^mb_i=x\)。由于 \(m\ge 2\),我们可以将第一项与后面 \(m-1\) 项分开来,即 \(b_1+\sum\limits_{i=2}^mb_i\)。根据题意前两个应当都 \(\in S\),也就是说如果一个数 \(x\) 可以表示成两个及以上的 \(T\) 中的数的和的必要条件是 \(\exists y,z\in S,s.t.y+z=x\),因此我们假设 \(S'\) 为可以表示成两个 \(S\) 中元素之和的 \(x\) 组成的集合,那么考虑分以下几种情况考虑:

  • 如果存在一个 \(x\in S'\) 但不属于 \(S\),那么根据题意可知 \(x\) 也应当可以被 \(T\) 中元素表示出来,与条件不符。
  • 如果不存在属于 \(S'\) 但不属于 \(S\) 的 \(S\),那么我们考虑 \(T=\{x|x\notin S',x\in S\}\),那么 \(T\) 即为所求。为什么呢?首先显然所有 \(x\in S',x\in S\) 的数必须都属于 \(T\),因为根据之前的分析,所有可以表示成两个即以上 \(T\) 中数的和的数都应当 \(\in S'\)。其次对于所有可以表示成两个及以上的数的 \(x\),也就是每个集合中的 \(x\),学过线性代数那一套理论的同学应该明白,删掉这样的 \(x\) 是不影响集合所有数能拼出的数的集合的,这样反复进行下去即可将 \(S'\) 删空,剩余的部分就是集合 \(T\) 了。因此集合 \(T\) 符合条件。

那么怎么求 \(S'\) 呢?其实非常 trivial()考虑幂级数 \(A(x)=\sum\limits_{i=1}^nx^{a_i}\),那么 \(S'\) 即为 \(A^2(x)\) 中系数非零且 \(\le m\) 的项组成的集合。FFT 求出即可。

时间复杂度 \(m\log m\)

const int MAXN=1e6;
const int MAXP=1<<21;
const double Pi=acos(-1);
int n,m,a[MAXN+5];
struct comp{
double x,y;
comp(double _x=0,double _y=0):x(_x),y(_y){}
comp operator +(const comp &rhs){return comp(x+rhs.x,y+rhs.y);}
comp operator -(const comp &rhs){return comp(x-rhs.x,y-rhs.y);}
comp operator *(const comp &rhs){return comp(x*rhs.x-y*rhs.y,x*rhs.y+y*rhs.x);}
} A[MAXP+5];
int rev[MAXP+5],LEN=1;
void FFT(comp *a,int len,int type){
int lg=31-__builtin_clz(len);
for(int i=0;i<len;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<lg-1);
for(int i=0;i<len;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);
for(int i=2;i<=len;i<<=1){
comp W(cos(2*Pi/i),type*sin(2*Pi/i));
for(int j=0;j<len;j+=i){
comp w(1,0);
for(int k=0;k<(i>>1);k++,w=w*W){
comp X=a[j+k],Y=a[(i>>1)+j+k]*w;
a[j+k]=X+Y;a[(i>>1)+j+k]=X-Y;
}
}
} if(!~type){
for(int i=0;i<len;i++) a[i].x=(int)(a[i].x/len+0.5);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1,x;i<=n;i++) scanf("%d",&x),a[x]++;
for(int i=1;i<=m;i++) A[i].x=a[i];
while(LEN<=(m+m)) LEN<<=1;FFT(A,LEN,1);
for(int i=0;i<LEN;i++) A[i]=A[i]*A[i];
FFT(A,LEN,-1);
// for(int i=1,v;i<=m;i++) printf("%d%c",(v=(int)(A[i].x))," \n"[i==m]);
for(int i=1,v;i<=m;i++) if((v=(int)(A[i].x))&&!a[i]) return puts("NO"),0;
vector<int> res;
for(int i=1,v;i<=m;i++) if(((v=(int)(A[i].x))>0)^a[i]) res.pb(i);
printf("YES\n%d\n",res.size());
for(int x:res) printf("%d ",x);
return 0;
}

upd on 2021.9.21:真·《好久没刷过》

https://codeforces.ml/contest/1574/problem/F

Codeforces 286E - Ladies' Shop(FFT)的更多相关文章

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

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

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

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

  3. codeforces#1154F. Shovels Shop (dp)

    题目链接: http://codeforces.com/contest/1154/problem/F 题意: 有$n$个物品,$m$条优惠 每个优惠的格式是,买$x_i$个物品,最便宜的$y_i$个物 ...

  4. Codeforces 528D Fuzzy Search(FFT)

    题目 Source http://codeforces.com/problemset/problem/528/D Description Leonid works for a small and pr ...

  5. codeforces 286E Ladies' Shop

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

  6. 2019.01.26 codeforces 528D. Fuzzy Search(fft)

    传送门 fftfftfft好题. 题意简述:给两个字符串s,ts,ts,t,问ttt在sss中出现了几次,字符串只由A,T,C,GA,T,C,GA,T,C,G构成. 两个字符匹配的定义: 当si−k, ...

  7. 快速傅里叶(FFT)的快速深度思考

    关于按时间抽取快速傅里叶(FFT)的快速理论深度思考 对于FFT基本理论参考维基百科或百度百科. 首先谈谈FFT的快速何来?大家都知道FFT是对DFT的改进变换而来,那么它究竟怎样改进,它改进的思想在 ...

  8. 【BZOJ3527】力(FFT)

    [BZOJ3527]力(FFT) 题面 Description 给出n个数qi,给出Fj的定义如下: \[Fj=\sum_{i<j}\frac{q_i q_j}{(i-j)^2 }-\sum_{ ...

  9. 【BZOJ4827】【HNOI2017】礼物(FFT)

    [BZOJ4827][HNOI2017]礼物(FFT) 题面 Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一 个送给她.每 ...

随机推荐

  1. Kali Linux修改root密码

    今天在官网下载了一个Kali虚拟机的压缩包, 解压缩后直接在VM中打开,点了好多次打开发现都打不开,查了一下说是没有关闭共享虚拟机,于是操作了一番: 编辑→首选项→共享虚拟机→选择禁用. 操作完之后果 ...

  2. 安卓开发——WebView+Recyclerview文章详情页,解决高度问题

    安卓开发--WebView+Recyclerview文章详情页,解决高度问题 最近在写一个APP时,需要显示文章详情页,准备使用WebView和RecyclerView实现上面文章,下面评论.出现了W ...

  3. Takin Talks·上海 |开源后首场主题研讨会来了,一起解密Takin技术吧!

      自 6 月 25 日全球首款生产环境全链路压测平台 Takin 正式开源,短短 13 天时间,Github 主页上 Star 数已超过 730,开发者社群也积累了 1500+粉丝.群内技术研讨氛围 ...

  4. [敏捷软工团队博客]Beta阶段项目展示

    团队成员简介和个人博客地址 头像 姓名 博客园名称 自我介绍 PM 测试 前端 后端 dzx 秃头院的大闸蟹 大闸蟹是1706菜市场里无菜可卖的底层水货.大闸蟹喜欢音乐(但可惜不会),喜欢lol(可惜 ...

  5. [技术博客]在团队中使用Pull Request来管理代码

    在团队中使用Pull Request来管理代码 前言 在参加多人共同开发项目,且选用Git作为代码托管工具的时候,我们不免会遇到分支冲突.覆盖.合并等问题.显然,因为同一个仓库是属于大家的,所以每个人 ...

  6. vue混入mixin的使用,保证你看的明明白白!

    场景描述 有些时候,我们发现有些组件部分功能代码是几乎是一样的. 这个时候,我们就可以将相同的逻辑代码抽离出来 此时我们的主角混入mixin就登场了 下面我们有a-test和b-test两个组件,点击 ...

  7. Python pip 和pip3区别 联系

    python 有python2和python3的区别 那么pip也有pip和pip3的区别 大概是这样的 pip是python的包管理工具,pip和pip3版本不同,都位于Scripts\目录下: 如 ...

  8. cf12E Start of the season(构造,,,)

    题意: 给一个偶数N. 构造出一个矩阵. 满足:主对角线上全为0.每一行是0~N-1的一个全排列.矩阵关于主对角线对称. 思路: 觉得是智商题,,,,看完题解后觉得不难,但是我就是没想出来.只想到了前 ...

  9. hdu 1158 Employment Planning(DP)

    题意: 有一个工程需要N个月才能完成.(n<=12) 给出雇佣一个工人的费用.每个工人每个月的工资.解雇一个工人的费用. 然后给出N个月所需的最少工人人数. 问完成这个项目最少需要花多少钱. 思 ...

  10. Netfilter和iptables介绍

    前言 在开始Kubernetes的网络之前我们先来学习Netfilter,Netfilter可能了解的人比较少,但是iptables用过 Linux的都应该知道.本文主要介绍Netfilter与ipt ...