ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF755G PolandBall and Many Other Balls

2021-11-19 07:31:27  阅读:172  来源: 互联网

标签:Balls int ll Ts long Other PolandBall RI define


题面传送门
首先我们设\(f_{i,j}\)表示到了第\(i\)个球,选了\(j\)个框的方案数,那么我们有\(f_{i,j}=f_{i-1,j}+f_{i-1,j-1}+f_{i-2,j-1}\)
然后我们又发现对于一个\(f_{i,j}\),我们可以拆成两个\(f_{\frac{i}{2},j}\)与两个\(f_{\frac{i}{2}-1,j-1}\)的卷积,所以我们可以倍增NTT
具体的,我们对于当前的\(n\),我们维护\(n,n-1,n-2\)的值,这样就可以推到\(2\times n,2\times n-1,2\times n-2\)了。
然后这样总共就是\(8\)次倍增NTT就可以求得答案了。
code:

#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define RI re int
#define ll long long
#define db double
#define lb long db
#define N (1<<16)
#define M 1000000
#define mod 998244353
#define Mod (mod-1)
#define eps (1e-4)
#define U unsigned int
#define it iterator
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
#define d(x,y) (n*(x-1)+(y))
#define R(n) (rand()*rand()%(n)+1)
#define Pc(x) putchar(x)
using namespace std;
int n,m,k,Ts,tr[N+5];
I ll mpow(ll x,int y=mod-2){ll Ans=1;while(y) y&1&&(Ans=Ans*x%mod),y>>=1,x=x*x%mod;return Ans;}const ll G=3,InvG=mpow(G);
I void NTT(ll *F,int n,int Fl){
	RI i,j,h;ll key,pus,now;for(i=0;i<n;i++) i<tr[i]&&(swap(F[i],F[tr[i]]),0);
	for(i=2;i<=n;i<<=1){
		for(key=mpow(Fl?G:InvG,(mod-1)/i),j=0;j<n;j+=i){
			for(pus=1,h=j;h<j+i/2;h++) now=pus*F[h+i/2]%mod,F[h+i/2]=(F[h]-now+mod)%mod,F[h]=(F[h]+now)%mod,pus=pus*key%mod;
		}
	}if(Fl) return;ll Invn=mpow(n);for(i=0;i<n;i++) F[i]=F[i]*Invn%mod;
}
struct Node{
	ll F[3][N+5],G[3][N+5],A[3][N+5],B[2][N+5];I void Ins(){memcpy(F[0],F[1],sizeof(F[1]));memcpy(F[1],F[2],sizeof(F[1]));for(RI i=0;i<=k;i++) F[2][i]=F[1][i],i&&(F[2][i]=(F[2][i]+F[1][i-1]+F[0][i-1])%mod);}
	I void Jump(){
		RI i,j;memcpy(G,F,sizeof(G));
		Me(A,0);Me(B,0);NTT(G[0],m,1);NTT(G[1],m,1);NTT(G[2],m,1);//NTT(G[0],m,0);NTT(G[1],m,0);NTT(G[2],m,0);
		for(i=0;i<m;i++) A[0][i]=G[1][i]*G[1][i]%mod,A[1][i]=G[2][i]*G[1][i]%mod,A[2][i]=G[2][i]*G[2][i]%mod,B[0][i]=G[0][i]*G[0][i]%mod,B[1][i]=G[0][i]*G[1][i]%mod;
		NTT(A[0],m,0);NTT(A[1],m,0);NTT(A[2],m,0);NTT(B[0],m,0);NTT(B[1],m,0);for(i=0;i<=k;i++) F[0][i]=A[0][i],F[1][i]=A[1][i],F[2][i]=A[2][i],i&&(F[0][i]+=B[0][i-1],F[1][i]+=B[1][i-1],F[2][i]+=A[0][i-1]);  
	}
}S;
I int Cnt(int x){int cnt=0;while(x) cnt++,x>>=1;return cnt;}
int main(){
	freopen("1.in","r",stdin);
	RI i,j;scanf("%d%d",&n,&k);for(m=1;m<=(k<<1);m<<=1);for(i=0;i<m;i++) tr[i]=(tr[i>>1]>>1)|((i&1)?m/2:0);
	S.F[0][0]=1;S.F[1][0]=S.F[1][1]=1;S.F[2][0]=1;S.F[2][1]=3;S.F[2][2]=1;
	if(n==1){for(i=1;i<=k;i++) printf("%lld ",S.F[1][i]);return 0;}
	if(n>2){Ts=Cnt(n)-1;if((n>>Ts-1)&1) S.Ins();for(i=Ts-2;~i;i--) S.Jump(),n>>i&1&&(S.Ins(),0);}
	for(i=1;i<=k;i++) printf("%lld ",S.F[2][i]%mod);
}

标签:Balls,int,ll,Ts,long,Other,PolandBall,RI,define
来源: https://www.cnblogs.com/275307894a/p/15575353.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有