题目

有一排 \(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. Eharts立体柱状图

    一下这三个div大小不一样 为了保证每次柱状图渲染正确 添加key <div class="echart1" id="dangerChart1" key= ...

  2. 异常处理try...except...finally---day26

    1.认识异常处理 # ### 认识异常处理 #IndexError 索引超出序列范围 #lst = [1,2,3,4] #print(lst[10]) #KeyError 字典中查找一个不存在的关键字 ...

  3. django学习第二天---django视图系统,基于类的视图写法,FBV和CBV加装饰器

    django视图系统 request对象 常用属性和方法 print(request) #wsgirequest对象 print(request.path) #请求路径 /index/ print(r ...

  4. 【Azure 批处理 】Azure Batch门户中创建自定义作业模式失败解决办法

    问题描述 跟随官方文档,快速创建Azure批处理任务(快速入门:在 Azure 门户中运行第一个 Batch 作业),在添加作业时,选择"自定义模式",并添加文档中所提供的简单命令 ...

  5. Java Servlet单元测试

    Java Servlet单元测试 1. 解决痛点 虽然目前主流的开发方式,很多都是通过controll或者微服务提供api.但是不免还是需要写几个servlet完成接口开发.按照常规,servlet调 ...

  6. Netty笔记(1) - Netty概述 和 框架结构

    概述 基于NIO 的框架,目的是简化开发NIO的工作量 异步的 ,基于事件驱动的网络应用程序框架,用以快速开发高性能.高可靠性的网络 IO 程序 Netty 是目前最流行的 NIO 框架,Netty ...

  7. IDEA使用与多线程

    IDEA缩写和快捷键 psvm全称public static void main sout 全称public static void main alt+enter 处理异常 s.out 自动打印s c ...

  8. 用json画图的画图软件 推荐 Balsamiq

    看这个库的时候发现的的这个软件 https://github.com/ironman1987/chinese-developer-roadmap 下载:https://www.zdfans.com/h ...

  9. 基于python的每日固定时间执行实例解析

    一 概念 datetime模块属性如下所示:   二 源码解析 该源码中,对时间库datetime应用十分到位,可以看作如下所示: import datetime import threading d ...

  10. AirPlay、DLNA、Miracast三大无线应用协议科普

    作为经常玩wifi的,wifi的应用层协议就要好好分析一下,做一些特殊的应用,还是非常有必要的.这里,就给学习一下wifi的三大无线传输技术. AirPlayAirPlay 是苹果开发的一种无线技术, ...