题目

有一排 \(n\) 个球,定义一个组可以只包含一个球或者包含两个相邻的球。

现在一个球只能分到一个组中,求从这些球中取出 \(k\) 组的方案数。

\(n\leq 10^9 ,k<2^{15}\)。


分析

设\(f[n][k]\)表示方案数,则

\[f[n][k]=f[n-1][k]+f[n-1][k-1]+f[n-2][k-1]
\]

考虑另一种转移方式就是

\[f[n+m][k]=\sum_{i=0}^kf[n][i]f[m][k-i]+\sum_{i=0}^{k-1}f[n-1][i]f[m-1][k-i-1]
\]

如果这些用生成函数\(f_n(x)\)表示的话就是

\[f_n(x)=f_{n-1}(x)+f_{n-1}(x-1)+f_{n-2}(x-1)
\]
\[f_{n+m}(x)=f_{n}(x)f_{m}(x)+xf_{n-1}(x)f_{m-1}(x)
\]

其实直接用下面这一条二进制拼凑结果即可,需要维护\(f_{n}(x),f_{n-1}(x),f_{n-2}(x)\)


代码

#include <cstdio>
#include <cctype>
#include <cmath>
#include <cstring>
#include <algorithm>
#define rr register
#define mem(f,n) memset(f,0,sizeof(int)*(n))
#define cpy(f,g,n) memcpy(f,g,sizeof(int)*(n))
using namespace std;
const int mod=998244353,inv3=332748118,N=70011;
typedef long long lll; typedef unsigned long long ull;
int n,m,Gmi[31],Imi[31],len,ff[3][N],ans[2][N],gg[3][N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline signed ksm(int x,int y){
rr int ans=1;
for (;y;y>>=1,x=1ll*x*x%mod)
if (y&1) ans=1ll*ans*x%mod;
return ans;
}
namespace Theoretic{
int rev[N],LAST; ull Wt[N],F[N];
inline void Pro(int n){
if (LAST==n) return; LAST=n,Wt[0]=1;
for (rr int i=0;i<n;++i)
rev[i]=(rev[i>>1]>>1)|((i&1)?n>>1:0);
}
inline void NTT(int *f,int n,int op){
Pro(n);
for (rr int i=0;i<n;++i) F[i]=f[rev[i]];
for (rr int o=1,len=1;len<n;++o,len<<=1){
rr int W=(op==1)?Gmi[o]:Imi[o];
for (rr int j=1;j<len;++j) Wt[j]=Wt[j-1]*W%mod;
for (rr int i=0;i<n;i+=len+len)
for (rr int j=0;j<len;++j){
rr int t=Wt[j]*F[i|j|len]%mod;
F[i|j|len]=F[i|j]+mod-t,F[i|j]+=t;
}
if (o==10) for (rr int j=0;j<n;++j) F[j]%=mod;
}
if (op==-1){
rr int invn=ksm(n,mod-2);
for (rr int i=0;i<n;++i) F[i]=F[i]%mod*invn%mod;
}else for (rr int i=0;i<n;++i) F[i]%=mod;
for (rr int i=0;i<n;++i) f[i]=F[i];
}
inline void trans_ans(){
for (rr int j=0;j<3;++j) cpy(gg[j],ff[j],len);
for (rr int j=0;j<3;++j) mem(gg[j]+n,len-n);
for (rr int j=0;j<3;++j) NTT(gg[j],len,1);
NTT(ans[0],len,1),NTT(ans[1],len,1);
for (rr int i=0;i<len;++i){
rr lll now0=ans[0][i],now1=ans[1][i];
ans[0][i]=now0*gg[0][i]%mod,gg[0][i]=now1*gg[1][i]%mod;
ans[1][i]=now0*gg[1][i]%mod,gg[1][i]=now1*gg[2][i]%mod;
}
NTT(ans[0],len,-1),NTT(ans[1],len,-1);
NTT(gg[0],len,-1),NTT(gg[1],len,-1);
for (rr int j=0;j<2;++j)
for (rr int i=1;i<len;++i)
ans[j][i]=(ans[j][i]+gg[j][i-1])%mod;
for (rr int j=0;j<2;++j) mem(ans[j]+n,len-n);
}
inline void trans(){
for (rr int j=0;j<3;++j) NTT(ff[j],len,1);
for (rr int i=0;i<len;++i){
rr lll now0=ff[0][i],now1=ff[1][i],now2=ff[2][i];
ff[0][i]=now0*now0%mod,gg[0][i]=now1*now1%mod;
ff[1][i]=now0*now1%mod,gg[1][i]=now1*now2%mod;
ff[2][i]=now1*now1%mod,gg[2][i]=now2*now2%mod;
}
for (rr int j=0;j<3;++j)
NTT(ff[j],len,-1),NTT(gg[j],len,-1);
for (rr int j=0;j<3;++j)
for (rr int i=1;i<len;++i)
ff[j][i]=(ff[j][i]+gg[j][i-1])%mod;
for (rr int j=0;j<3;++j) mem(ff[j]+n,len-n);
}
}
inline void GmiImi(){
for (rr int i=0;i<31;++i) Gmi[i]=ksm(3,(mod-1)/(1<<i));
for (rr int i=0;i<31;++i) Imi[i]=ksm(inv3,(mod-1)/(1<<i));
}
signed main(){
m=iut(),n=iut()+1,GmiImi();
for (len=1;len<n*2;len<<=1);
ff[0][0]=ff[1][0]=ff[0][1]=ans[0][0]=1;
for (rr int t=1;t<=m;t<<=1){
if (m&t) Theoretic::trans_ans();
Theoretic::trans();
}
for (rr int i=1;i<n;++i)
print(ans[0][i]),putchar(32);
return 0;
}

#倍增FFT#CF755G PolandBall and Many Other Balls的更多相关文章

  1. 题解-CF755G PolandBall and Many Other Balls

    题面 CF755G PolandBall and Many Other Balls 给定 \(n\) 和 \(m\).有一排 \(n\) 个球,求对于每个 \(1\le k\le m\),选出 \(k ...

  2. CF755G PolandBall and Many Other Balls/soj 57送饮料

    题意:长度为n的序列,相邻两个或单独一个可以划分到一个组,每个元素最多处于一个组. 问恰好分割成k(1<=k<=m)段有多少种方案? 标程: #include<bits/stdc++ ...

  3. CF755G PolandBall and Many Other Balls 题解

    从神 Karry 的题单过来的,然后自己瞎 yy 了一个方法,看题解区里没有,便来写一个题解 一个常数和复杂度都很大的题解 令 \(dp_{i,j}\) 为 在 \(i\) 个球中选 \(j\) 组的 ...

  4. CF755G-PolandBall and Many Other Balls【倍增FFT】

    正题 题目链接:https://www.luogu.com.cn/problem/CF755G 题目大意 \(n\)个东西排成一排,每个组可以选择一个单独的物品或者两个连续的物品,一个物品不同同时在两 ...

  5. FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅱ

    因为垃圾电脑太卡了就重开了一个... 前传:多项式Ⅰ u1s1 我预感还会有Ⅲ 多项式基础操作: 例题: 26. CF438E The Child and Binary Tree 感觉这题作为第一题还 ...

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

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

  7. CodeForces 553E Kyoya and Train 动态规划 多项式 FFT 分治

    原文链接http://www.cnblogs.com/zhouzhendong/p/8847145.html 题目传送门 - CodeForces 553E 题意 一个有$n$个节点$m$条边的有向图 ...

  8. 快速傅里叶变换FFT / NTT

    目录 FFT 系数表示法 点值表示法 复数 DFT(离散傅里叶变换) 单位根的性质 FFT(快速傅里叶变换) IFFT(快速傅里叶逆变换) NTT 阶 原根 扩展知识 FFT 参考blog: 十分简明 ...

  9. 北京培训记day1

    数学什么的....简直是丧心病狂啊好不好 引入:Q1:前n个数中最多能取几个,使得没有一个数是另一个的倍数   答案:(n/2)上取整 p.s.取后n/2个就好了 Q2:在Q1条件下,和最小为多少 答 ...

  10. NOI前的考试日志

    4.14 网络流专项测试 先看T1,不会,看T2,仙人掌???wtf??弃疗.看T3,貌似最可做了,然后开始刚,刚了30min无果,打了50分暴力,然后接着去看T1,把序列差分了一下,推了会式子,发现 ...

随机推荐

  1. 【Android 逆向】【攻防世界】app2

    1. 手机安装apk,随便点击,进入到第二个页面就停了 2. jadx打开apk,发现一共有三个activity,其中第三个activity: FileDataActivity 里面有东西 publi ...

  2. Qt开发技术:QCharts(二)QCharts折线图介绍、Demo以及代码详解

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  3. xadmin后台的安装及配置使用

    安装 pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2 在settings.py中注册如下应用 INSTALLED_ ...

  4. django中update_or_create()

    update_or_create()方法中有一个defaults参数 模型字段会根据查询条件进行查询,如果查询到了,那么就用defaults对应的值去更新字段,如果没有查到就用defaults对应的值 ...

  5. Ubuntu防火墙相关

    查看防火墙当前状态 sudo ufw status 开启防火墙 sudo ufw enable 关闭防火墙 sudo ufw disable 查看防火墙版本 sudo ufw version 默认允许 ...

  6. 学Python只需一张图

    有编程基础的人一看就可以了解 Python 的用法了.真正的 30 分钟上手.

  7. iOS上拉边界下拉白色空白问题解决概述

    表现 手指按住屏幕下拉,屏幕顶部会多出一块白色区域.手指按住屏幕上拉,底部多出一块白色区域. 产生原因 在 iOS 中,手指按住屏幕上下拖动,会触发 touchmove 事件.这个事件触发的对象是整个 ...

  8. 【Azure ACR+App Service】ACR WebHook请求App Service时遇见 401 Unauthorized

    问题描述 App Service 支持从ACR中直接拉取镜像,并且可以配置持续部署(Continuous Deployment), 它是通过在ACR中添加一个Webhook,然后发送POST请求到 & ...

  9. cw attack

  10. 【2024面试刷题】一、Spring Cloud 面试题

    1.什么是 Spring Cloud? Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如 服务发现注册.配置中心.智能路 ...