[题解] LuoguP3784 [SDOI2017]遗忘的集合
要mtt的题都是......
多补了几项就被卡了一整页......果然还是太菜了......
不说了......来看100分的做法吧......
如果做过付公主的背包,前面几步应该不难想,所以我们再来写一遍柿子。
首先令\(c_i = [0,1]\)表示数\(i\)是否在集合中,那么\(f\)的生成函数就是
\]
乘法不太好做,我们两边\(\ln\)一下,转化成加法
\]
我们想要右边的\(\ln\)变得好看一点,这个柿子在付公主的背包里好像推过了......这里就不写了。
柿子是
\]
带上去再做一些变化
\]
我们枚举\(k = ij\)
\]
我们令\(f'_k\)表示\(\ln F(x)\)的\(i\)次项系数\(\times k\),知道了\(f'_k = \sum\limits_{i \mid k} c_i i\)
那么我们要构造一组\(c\),使得答案的字典序最小。字典序这个东西有很强的可贪性......
我们肯定会先考虑较小的\(i\),然后我们又知道对于能被\(i\)整除的\(j\),也就是\(i \mid j\),有\(f'_j \ge f'_i\),因为能对\(i\)产生贡献的\(c_k\),对\(j\)也会产生贡献。
所以当我们把\(f'\)求出来的时候,做一个类似筛法的东西,\(\forall j, i\mid j\),让\(f'_j\)减\(f'_i\)。
最后剩下类非\(0\)的\(f'_i\),\(i\)就是在一个集合内的数,这样复杂度是对的。
然而需要MTT,异常duliu......
得到了一个教训......代码中的limit
不可以瞎开......
\(Code:\)(只会写辣鸡版本的MTT......)
#include <bits/stdc++.h>
using namespace std;
typedef long double db;
typedef long long ll;
const db PI=acos(-1.0);
const int N=8e5+10;
int mod;
inline int fpow(int x,int y){
int ret=1; for(x%=mod;y;y>>=1,x=1ll*x*x%mod)
if(y&1) ret=1ll*ret*x%mod;
return ret;
}
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int sub(int x,int y){return x-y<0?x-y+mod:x-y;}
namespace Poly{
struct cpl{
db x,y;
cpl operator + (cpl k1)const{return (cpl){x+k1.x,y+k1.y};}
cpl operator - (cpl k1)const{return (cpl){x-k1.x,y-k1.y};}
cpl operator * (cpl k1)const{return (cpl){x*k1.x-y*k1.y,x*k1.y+y*k1.x};}
};
int rev[N];
void init(int n){
for(int i=0;i<n;i++)
rev[i]=rev[i>>1]>>1|((i&1)?n>>1:0);
}
void fft(cpl *f,int n,int flg){
for(int i=0;i<n;i++) if(rev[i]<i) swap(f[i],f[rev[i]]);
for(int len=2,k=1;len<=n;len<<=1,k<<=1){
cpl wn=(cpl){cos(2*PI/len),flg*sin(2*PI/len)};
for(int i=0;i<n;i+=len){
cpl w=(cpl){1,0};
for(int j=i;j<i+k;j++,w=w*wn){
cpl tmp=w*f[j+k];
f[j+k]=f[j]-tmp,f[j]=f[j]+tmp;
}
}
}
if(flg==-1) for(int i=0;i<n;i++)
f[i].x/=n;
}
void mtt(int *a,int *b,int *c,int n){
static cpl f[2][N],g[2][N],ans[3][N];
for(int i=0;i<n;i++){
f[0][i]=(cpl){(db)(a[i]>>15),0};
f[1][i]=(cpl){(db)(a[i]&0x7fff),0};
g[0][i]=(cpl){(db)(b[i]>>15),0};
g[1][i]=(cpl){(db)(b[i]&0x7fff),0};
}
fft(f[0],n,1),fft(f[1],n,1),fft(g[0],n,1),fft(g[1],n,1);
for(int i=0;i<n;i++){
ans[0][i]=f[0][i]*g[0][i];
ans[1][i]=f[0][i]*g[1][i]+f[1][i]*g[0][i];
ans[2][i]=f[1][i]*g[1][i];
}
fft(ans[0],n,-1),fft(ans[1],n,-1),fft(ans[2],n,-1);
#define normal(x) (((ll)((x)+0.5)%mod+mod)%mod)
for(int i=0;i<n;i++){
ll t1=(normal(ans[0][i].x)<<30ll)%mod;
ll t2=(normal(ans[1][i].x)<<15ll)%mod,t3=normal(ans[2][i].x);
c[i]=((t1+t2)%mod+t3)%mod;
}
}
void dao(int *f,int n,int *G){
static int F[N]; for(int i=0;i<=n;i++) F[i]=f[i];
for(int i=1;i<=n;i++) G[i-1]=1ll*F[i]*i%mod; G[n]=0;
}
void jifen(int *f,int n,int *G){
static int F[N]; for(int i=0;i<=n;i++) F[i]=f[i];
for(int i=0;i<=n;i++) G[i+1]=1ll*F[i]*fpow(i+1,mod-2)%mod; G[0]=0;
}
void getinv(int *f,int n,int *G){
if(n==1){G[0]=fpow(f[0],mod-2);return;}
getinv(f,(n+1)>>1,G);
static int F[N],H[N],H1[N];
int limit=1; while(limit<=(n-1)*2)limit<<=1; init(limit);
for(int i=0;i<n;i++) H[i]=G[i],F[i]=f[i];
for(int i=n;i<limit;i++) H[i]=F[i]=G[i]=0;
mtt(F,G,H1,limit);
H1[0]=sub(2,H1[0]);
for(int i=1;i<limit;i++) H1[i]=i<n?mod-H1[i]:0;
for(int i=n;i<limit;i++) H1[i]=0;
mtt(H,H1,G,limit);
for(int i=n;i<limit;i++) G[i]=0;
}
void getln(int *f,int n,int *G){
static int F[N],iF[N]; for(int i=0;i<n;i++) F[i]=f[i];
getinv(F,n,iF),dao(F,n-1,F);
int limit=1; while(limit<=(n-1)*2)limit<<=1; init(limit);
mtt(F,iF,G,limit);
jifen(G,n-1,G); for(int i=n;i<limit;i++) G[i]=0;
}
}
int n,f[N],ans[N];
int main(){
scanf("%d%d",&n,&mod);
f[0]=1; for(int i=1;i<=n;i++) scanf("%d",&f[i]);
Poly::getln(f,n+1,ans);
for(int i=1;i<=n;i++) ans[i]=1ll*ans[i]*i%mod;
for(int i=1;i<=n;i++)
for(int j=i*2;j<=n;j+=i) ans[j]=sub(ans[j],ans[i]);
int cnt=0;
for(int i=1;i<=n;i++) if (ans[i]) ++cnt;
printf("%d\n",cnt);
for(int i=1;i<=n;i++) if(ans[i]) printf("%d ",i);
return 0;
}
[题解] LuoguP3784 [SDOI2017]遗忘的集合的更多相关文章
- [SDOI2017]遗忘的集合
[SDOI2017]遗忘的集合 综合了很多套路的题 一看就是完全背包 生成函数! 转化为连乘积形式 Pi....=F 求Ln! 降次才可以解方程 发现方程是: f[i]=∑t|i : bool(t)* ...
- 洛谷P3784 [SDOI2017]遗忘的集合(生成函数)
题面 传送门 题解 生成函数这厮到底还有什么是办不到的-- 首先对于一个数\(i\),如果存在的话可以取无限多次,那么它的生成函数为\[\sum_{j=0}^{\infty}x^{ij}={1\ove ...
- [BZOJ4913][SDOI2017]遗忘的集合
题解: 首先先弄出$f(x)$的生成函数$$f(x)=\prod_{i=1}^{n} {{(\frac{1}{1-x^i})}}^{a[i]}$$因为$f(x)$已知,我们考虑利用这个式子取推出$a[ ...
- [LOJ2271] [SDOI2017] 遗忘的集合
题目链接 LOJ:https://loj.ac/problem/2271 洛谷:https://www.luogu.org/problemnew/show/P3784 BZOJ太伤身体死活卡不过还是算 ...
- SDOI2017遗忘的集合
题面链接 咕咕咕 题外话 为了这道题我敲了\(MTT\).多项式求逆.多项式\(ln\)等模板,搞了将近一天. sol 最近懒得写题解啊,随便搞搞吧. 看到这个就是生成函数套上去. \[F(x)=\p ...
- P3784 [SDOI2017]遗忘的集合
非常神仙的一道题! 题意:给出某n个数字跑完全背包m容量的dp数组,求满足要求的字典序最小的n个元素,不知道n是多少. 首先考虑付公主的背包这个题. 对dp数组求一个ln,设它为F. 已知 e^(G1 ...
- 洛谷 3784(bzoj 4913) [SDOI2017]遗忘的集合——多项式求ln+MTT
题目:https://www.luogu.org/problemnew/show/P3784 https://www.lydsy.com/JudgeOnline/problem.php?id=4913 ...
- BZOJ 4913 [Sdoi2017] 遗忘的集合
骂了隔壁的 BZOJ垃圾评测机 我他妈卡了两页的常数了 我们机房的电脑跑的都比BZOJ快
- 【题解】LOJ2462完美的集合(树DP 魔改Lucas)
[题解]LOJ2462完美的集合(树DP 魔改Lucas) 省选模拟考这个??????????????????? 题目大意: 有一棵树,每个点有两个属性,一个是重量\(w_i\)一个是价值\(v_i\ ...
随机推荐
- Scrapy 使用 LinkExtractor 提取链接和使用 Exporter 导出数据
在爬取一个网站时,想要爬取的数据通常分布到多个页面中,每个页面包含一部分数据以及其他页面的链接,提取链接有使用 Selector 和使用 Linkextractor 两种方法. 1.使用Selecto ...
- 报警视图 报警窗口 报警指示器 的组态 PLC变量 事故信息 MW16 报警确认变量 MW18 转速变量 MW20 温度变量 MW22 用 M17.0 来模拟事故信息的最低位。用PLCSIM 给定温度为800 度 报警视图与报警窗口显示故障
组态报警并用PLCSIM进行仿真 步骤1 : 组态离散变量报警 在PLC 的默认变量表中 创建变量"事故信息" 数据类型是word 绝对地址是MW16 同时建立 报警确认变量 MW ...
- Xshell 5的快捷键
Xshell 5的快捷键 1. 点击下图中的按钮查看快捷键: 2. 快捷键备忘录: 序号 功能 快捷键 备注 1 在窗口和撰写栏之间切换 Alt+I 2 全屏 Alt+Enter 3 ...
- Linux centosVMware 命令 lvm、磁盘故障小案例
一.lvm命令 LVM:逻辑分区管理,可基于动态的扩展缩小硬件设备的使用空间,注意:lvm磁盘复杂,由于使用lvm,数据丢失恢复起来有一定风险.概念:pv.VG.lvpv(物理卷,有pp基本单位构成) ...
- 「POI2017」Flappy Bird
传送门 Luogu团队题 解题思路 数据范围不小啊,离散也不行,DP不了,考虑贪心+递推. 我们递推出小鸟可以到达的高度区间. 我们发现,小鸟最好的情况就是在当前基础上,从最下方一直往下飞,或者从最上 ...
- 嵊州普及Day3T1
题意:n座山,每天袭击k面,不能为同一座.问最少几天袭击所有山两面. 思路:不管如何,n,k<=10,做了就能过,考试时先想的暴力模拟,后来发现有规律,看看就好了. 见代码: #include& ...
- asp.net获取时间日期插入数据库
//获取日期+时间 DateTime.Now.ToString(); // 2008-9-4 20:02:10 DateTime.Now.ToLocalTime().ToString(); // 20 ...
- 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:接口的基本实现
interface A{ // 定义接口A public static final String AUTHOR = "李兴华" ; // 全局常量 public abstract ...
- greenplum 存储过程 输出信息
raise notice 'just a simple output msg';
- fuseki远程访问方法
./fuseki-server启动服务后,我们的服务只能是localhost访问,无法被其他人访问,那么 要怎么修改呢.很简单,把apche-jena-fuseki-3.10.0/run 下面的shi ...