【2020-2021集训队作业】春天,在积雪下结一成形,抽枝发芽

【2020-2021集训队作业】春天,在积雪下结一成形,抽枝发芽

Description

计数不存在非平凡(长为\(1\)\(n\))连续段使得其值域也是连续的的\(n\)阶排列个数

\(998244353\)

Input

一行两个数\(ty,n\)

Output

\(ty=0\)时输出\(n\)的答案

\(ty=1\)时输出\(1\sim n\)的答案

Sample Input

1 4

Sample Output

1
2
0
2

Data Constraint

\(1\le n\le 10^5\)

Solution

不妨先考虑合点的情况

设排列的OGF为\(H(x)\),根为合点的OGF为\(G(x)\)

显然合点可以用\(n!\)减去只有一个儿子的情况

那么

\[G(x)=\sum_{i\ge 2}(H-G)^i=\frac{H^2}{1+H} \]

然后考虑根为析点的情况

\(F(x)\)为答案

那么由于任意大于\(1\)的段都不合法,所以析点可以用复合来表示

\[\sum_{i\ge 4}f_iH(x)^i=F(H(x)) \]

然后有

\[F(H(x))+2G+x=H(x) \]

考虑\(H(x)\)的复合逆\(P(x)\)

那么

\[F(x)=x-\frac{2x^2}{1+x}-P(x) \]

\(H(x)\)的ODE比较经典,然后结合\(H(P)'=x'=1=H'(P)P'\),就得到了

\[P^2+(x+1)PP'-xP'=0 \]

半在线卷积就行了

Code

#include<bits/stdc++.h>
using namespace std;
#define F(i,a,b) for(int i=a;i<=b;i++)
#define Fd(i,a,b) for(int i=a;i>=b;i--)
#define N 600010
#define mo 998244353
#define LL long long
#define ULL unsigned long long

int rev[N],G1[N],G2[N],fac[N],ifac[N],inv[N];

int mod(int x){return x>=mo?x-mo:x;}

int mi(int x,int y){
	if(!y)return 1;
	if(y==1)return x;
	return y%2?1ll*x*mi(1ll*x*x%mo,y/2)%mo:mi(1ll*x*x%mo,y/2);
}

void init(){
	fac[0]=ifac[0]=1;
	F(i,1,N-10)fac[i]=1ll*fac[i-1]*i%mo,inv[i]=(i==1?1:1ll*mo/i*mod(mo-1ll*inv[mo%i]%mo)%mo);
	ifac[N-10]=mi(fac[N-10],mo-2);
	Fd(i,N-11,1)ifac[i]=1ll*ifac[i+1]*(i+1)%mo;
	for(int l=1;l<=N-10;l<<=1)G1[l]=mi(3,(mo-1)/(l*2)),G2[l]=mi(G1[l],mo-2);
}

void BRT(int x){F(i,0,x-1)rev[i]=(rev[i>>1]>>1)|((i&1)?(x>>1):0);}

struct poly{
	vector<int>val;
	poly(int x=0){if(x)val.push_back(x);}
	poly(const vector<int>&x){val=x;}
	void ins(int x){val.push_back(x);}
	void clear(){vector<int>().swap(val);}
	int sz(){return val.size();}
	void rsz(int x){val.resize(x);}
	void shrink(){for(;sz()&&!val.back();val.pop_back());}
	void Rev(){reverse(val.begin(),val.end());} 
	poly modxn(int x){
		if(val.size()<=x)return poly(val);
		else return poly(vector<int>(val.begin(),val.begin()+x));
	}
	int operator[](int x)const{
		if(x<0||x>=val.size())return 0;
		return val[x];
	}
	void NTT(int x){
		static ULL f[N],w[N];
		w[0]=1;
		F(i,0,sz()-1)f[i]=(((LL)mo<<5)+val[rev[i]])%mo;
		for(int mid=1;mid<sz();mid<<=1){
			int tmp=(x==1?G1[mid]:G2[mid]);
			F(i,1,mid-1)w[i]=w[i-1]*tmp%mo;
			for(int i=0;i<sz();i+=(mid<<1)){
				F(j,0,mid-1){
					int t=w[j]*f[i|j|mid]%mo;
					f[i|j|mid]=f[i|j]+mo-t;f[i|j]+=t;
				}
			}
			//if(mid==(1<<10)){F(i,0,sz()-1)f[i]%=mo;};
		}
		if(x==-1){int tmp=inv[sz()];F(i,0,sz()-1)val[i]=f[i]%mo*tmp%mo;}
		else{F(i,0,sz()-1)val[i]=f[i]%mo;}
	}
	void DFT(){NTT(1);}
	void IDFT(){NTT(-1);}
	friend poly operator*(poly x,poly y){
		if(x.sz()<30||y.sz()<30){
			if(x.sz()>y.sz())swap(x,y);
			poly ret;
			ret.rsz(x.sz()+y.sz());
			F(i,0,ret.sz()-1){
				for(int j=0;j<=i&&j<x.sz();j++)
					ret.val[i]=mod(ret.val[i]+1ll*x[j]*y[i-j]%mo);
			}
	//		ret.shrink();
			return ret;
		}
		int l=1;
		while(l<x.sz()+y.sz()-1)l<<=1;
		x.rsz(l);y.rsz(l);BRT(l);
		x.DFT();y.DFT();
		F(i,0,l-1)x.val[i]=1ll*x[i]*y[i]%mo;
		x.IDFT();
	//	x.shrink();
		return x;
	}
	friend poly operator+(poly x,poly y){
		poly ret;
		ret.rsz(max(x.sz(),y.sz()));
		F(i,0,ret.sz()-1)ret.val[i]=mod(x[i]+y[i]);
		return ret;
	}
	friend poly operator-(poly x,poly y){
		poly ret;
		ret.rsz(max(x.sz(),y.sz()));
		F(i,0,ret.sz()-1)ret.val[i]=mod(x[i]-y[i]+mo);
		return ret;
	}
	poly &operator*=(poly x){return (*this)=(*this)*x;}
	poly &operator+=(poly x){return (*this)=(*this)+x;}
	poly &operator-=(poly x){return (*this)=(*this)-x;}
	poly deriv(){
		poly f;
		f.rsz(sz()-1);
		F(i,0,sz()-2)f.val[i]=1ll*(i+1)*val[i+1]%mo;
		return f;
	}
	poly integ(){
		poly f;
		f.rsz(sz()+1);
		F(i,1,sz())f.val[i]=1ll*val[i-1]*inv[i]%mo;
		return f;
	}
	poly inver(int Len){
		poly f,g,res(mi(val[0],mo-2));
		for(int i=1;i<Len;){
			i<<=1;f.rsz(i);g.rsz(i);BRT(i);
			F(j,0,i-1)f.val[j]=(*this)[j],g.val[j]=res[j];
			f.DFT();g.DFT();
			F(j,0,i-1)f.val[j]=1ll*f[j]*g[j]%mo;
			f.IDFT();
			F(j,0,(i>>1)-1)f.val[j]=0;
			f.DFT();
			F(j,0,i-1)f.val[j]=1ll*f[j]*g[j]%mo;
			f.IDFT();
			res.rsz(i);
			F(j,i>>1,i-1)res.val[j]=mod(mo-f[j]);
		}
		return res.modxn(Len);
	}
	poly Sqrt(int Len){
		int i2=inv[2];
		poly f,g,tmp;
		f.clear();g.clear();
		g.ins(1);
		for(int i=1;i<Len*2;i<<=1){
			int Len=i<<1;
			f.rsz(Len);
			tmp=g.inver(i);
			tmp.rsz(Len);
			BRT(Len);
			F(j,0,i-1)f.val[j]=(j<val.size()?val[j]:0);
			f.DFT();tmp.DFT();
			F(j,0,Len-1)f.val[j]=1ll*f[j]*tmp[j]%mo;
			f.IDFT();
			g.rsz(i);
			F(j,0,i-1)g.val[j]=1ll*i2*mod(g[j]+f[j])%mo;
		}
		return g.modxn(Len);
	}
	poly Ln(int Len){
		return (deriv()*inver(Len)).integ().modxn(Len);
	}
	poly Exp(int Len){
		poly f;
		f.clear();
		f.ins(1);
		for(int i=2;i<Len*2;i<<=1)f=(f*(1-f.Ln(i)+modxn(i))).modxn(i);
		return f.modxn(Len);
	}
	poly Pow(int Len,int k){
		poly f;
		f.clear();
		int tail=0;
		while(val[tail]==0&&tail<sz())tail++;
		if(tail>=sz())return f;
		if(tail*k>=Len)return f;
		f.rsz(Len);
		int Mul=mi(val[tail],mo-2);
		F(i,0,min(Len-1,sz()-tail-1))f.val[i]=1ll*val[i+tail]*Mul%mo;
		Mul=mi(val[tail],k);
		f=f.Ln(Len);
		F(i,0,Len-1)f.val[i]=1ll*f[i]*(k%mo)%mo;
		f=f.Exp(Len);
		Fd(i,Len-1,tail*k)f.val[i]=1ll*f[i-tail*k]*Mul%mo;
		F(i,0,tail*k-1)f.val[i]=0;
		return f;
	}
};

int ty,n;
poly f;

void solve(int l,int r){
	if(l==r)return;
	int mid=l+r>>1;
	poly p,q;
	if(l==1){
		solve(l,mid);
		p.clear();q.clear();
		F(i,0,mid)p.ins(1ll*(i+1)*f[i]%mo);
		F(i,0,mid)q.ins(f[i]);
		p*=q;
		F(i,mid+1,r)f.val[i]=mod(f[i]-p[i]+mo);
		p.clear();q.clear();
		F(i,0,mid)p.ins(1ll*i*f[i]%mo);
		F(i,0,mid)q.ins(f[i]);
		p*=q;
		F(i,mid+1,r)f.val[i]=mod(f[i]-p[i+1]+mo);
		solve(mid+1,r);
	}else{
		solve(l,mid);
		p.clear();q.clear();
		F(i,l,mid)p.ins(1ll*(i+1)*f[i]%mo);
		F(i,0,r-l)q.ins(f[i]);
		p*=q;
		F(i,mid+1,r)f.val[i]=mod(f[i]-p[i-l]+mo);
		p.clear();q.clear();
		F(i,l,mid)p.ins(1ll*i*f[i]%mo);
		F(i,0,r-l+1)q.ins(f[i]);
		p*=q;
		F(i,mid+1,r)f.val[i]=mod(f[i]-p[i-l+1]+mo);
		p.clear();q.clear();
		F(i,0,r-l)p.ins(1ll*(i+1)*f[i]%mo);
		F(i,l,mid)q.ins(f[i]);
		p*=q;
		F(i,mid+1,r)f.val[i]=mod(f[i]-p[i-l]+mo);
		p.clear();q.clear();
		F(i,0,r-l+1)p.ins(1ll*i*f[i]%mo);
		F(i,l,mid)q.ins(f[i]);
		p*=q;
		F(i,mid+1,r)f.val[i]=mod(f[i]-p[i-l+1]+mo);
		solve(mid+1,r);
	}
}

int main(){
	init();
	scanf("%d%d",&ty,&n);
	f.rsz(n+1);
	f.val[1]=1;
	solve(1,n);
	f.val[1]=1;f.val[2]=2;
	F(i,3,n){
		f.val[i]=mod(mo-f[i]);
		f.val[i]=mod(f[i]+(i&1?2:mo-2));
	}
	if(!ty){printf("%d",f[n]);return 0;}
	F(i,1,n)printf("%d\n",f[i]);
	return 0;
}
posted @ 2023-02-28 21:32  冰雾  阅读(44)  评论(0编辑  收藏  举报