#倍增FFT#CF755G PolandBall and Many Other Balls
题目
有一排 \(n\) 个球,定义一个组可以只包含一个球或者包含两个相邻的球。
现在一个球只能分到一个组中,求从这些球中取出 \(k\) 组的方案数。
\(n\leq 10^9 ,k<2^{15}\)。
分析
设\(f[n][k]\)表示方案数,则
\]
考虑另一种转移方式就是
\]
如果这些用生成函数\(f_n(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的更多相关文章
- 题解-CF755G PolandBall and Many Other Balls
题面 CF755G PolandBall and Many Other Balls 给定 \(n\) 和 \(m\).有一排 \(n\) 个球,求对于每个 \(1\le k\le m\),选出 \(k ...
- CF755G PolandBall and Many Other Balls/soj 57送饮料
题意:长度为n的序列,相邻两个或单独一个可以划分到一个组,每个元素最多处于一个组. 问恰好分割成k(1<=k<=m)段有多少种方案? 标程: #include<bits/stdc++ ...
- CF755G PolandBall and Many Other Balls 题解
从神 Karry 的题单过来的,然后自己瞎 yy 了一个方法,看题解区里没有,便来写一个题解 一个常数和复杂度都很大的题解 令 \(dp_{i,j}\) 为 在 \(i\) 个球中选 \(j\) 组的 ...
- CF755G-PolandBall and Many Other Balls【倍增FFT】
正题 题目链接:https://www.luogu.com.cn/problem/CF755G 题目大意 \(n\)个东西排成一排,每个组可以选择一个单独的物品或者两个连续的物品,一个物品不同同时在两 ...
- FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅱ
因为垃圾电脑太卡了就重开了一个... 前传:多项式Ⅰ u1s1 我预感还会有Ⅲ 多项式基础操作: 例题: 26. CF438E The Child and Binary Tree 感觉这题作为第一题还 ...
- 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】
原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...
- CodeForces 553E Kyoya and Train 动态规划 多项式 FFT 分治
原文链接http://www.cnblogs.com/zhouzhendong/p/8847145.html 题目传送门 - CodeForces 553E 题意 一个有$n$个节点$m$条边的有向图 ...
- 快速傅里叶变换FFT / NTT
目录 FFT 系数表示法 点值表示法 复数 DFT(离散傅里叶变换) 单位根的性质 FFT(快速傅里叶变换) IFFT(快速傅里叶逆变换) NTT 阶 原根 扩展知识 FFT 参考blog: 十分简明 ...
- 北京培训记day1
数学什么的....简直是丧心病狂啊好不好 引入:Q1:前n个数中最多能取几个,使得没有一个数是另一个的倍数 答案:(n/2)上取整 p.s.取后n/2个就好了 Q2:在Q1条件下,和最小为多少 答 ...
- NOI前的考试日志
4.14 网络流专项测试 先看T1,不会,看T2,仙人掌???wtf??弃疗.看T3,貌似最可做了,然后开始刚,刚了30min无果,打了50分暴力,然后接着去看T1,把序列差分了一下,推了会式子,发现 ...
随机推荐
- Go语言并发编程(3):sync包介绍和使用(上)-Mutex,RWMutex,WaitGroup,sync.Map
一.sync 包简介 在并发编程中,为了解决竞争条件问题,Go 语言提供了 sync 标准包,它提供了基本的同步原语,例如互斥锁.读写锁等. sync 包使用建议: 除了 Once 和 WaitGro ...
- 【Android 逆向】【ARM汇编】 事前更新和事后更新
1. 事前更新,事后更新,不更新 不更新 ldr R4, [R1, R2, lsl #1] 相当于 R4 = *(R1 + R2 << 2^1) 之后 R1.R2的值时没有变化的 事前更新 ...
- JavaScript的引入并执行-包含动态引入与静态引入
JavaScript的引入并执行-包含动态引入与静态引入 JavaScript引入方式 html文件需要引入JavaScript代码,才能在页面里使用JavaScript代码. 静态引入 行内式 直接 ...
- error接口
// 实际上它是interface类型,这个类型有一个返回错误信息的单一方法: type error interface{ Error() string } 创建一个error最简单的方法就是调用er ...
- docker-compose 安装gitlab
准备docker-compose.yml version: '3.6' services: web: image: 'registry.gitlab.cn/omnibus/gitlab-jh:16.7 ...
- 【Azure App Service】App Service设置访问限制后,使用git clone代码库出现403报错
问题描述 在App Service中,为App Service配置了访问限制,结果导致在克隆App Service的代码时候,遇见403错误. 问题解答 因为在使用 git clone App Ser ...
- 【Azure Redis 缓存 Azure Cache For Redis】Redis支持的版本及不同版本迁移风险
问题描述 1. Azure Redis缓存支持的版本包括4.0以及6.0(预览) 这种情形下,可以使用PaaS服务提供的 Azure Redis 缓存(4.0版本).Azure Redis对6.0的支 ...
- 【Azure 事件中心】如何查看事件中心的消息中具体报文内容呢?
问题描述 如何查看事件中心的消息中具体报文内容呢? 问题解答 正常情况是通过 Event Hub 的消费端获取消息进行处理查看,但是没有客户端代码的情况下,也可以通过微软的默认客户端Service B ...
- RocketMQ(1) 基础介绍和单机-集群安装
1. MQ简单介绍 1.1 应用场景 应用解耦 系统的耦合性越高,容错性就越低.以电商应用为例,用户创建订单后,如果耦合调用库存系统.物流系统.支付系统,任何一个子系统出了故障或者因为升级等原因暂时不 ...
- Git 常用的基础命令
#克隆项目到本地.url:项目的git地址:local_dir_name:克隆项目到本地的目录名称,如果不写就默认是git项目中的目录名称 git clone <url> <loca ...