LGP6694题解

第一眼似乎很困难,实际上非常简单(

好吧这题我做了一个小时(

首先期望具有线性性,我们转化为计算点对对答案的贡献。

发现相对位置一样的点对对答案的贡献是一样的。我们把相对位置一样的点对铃出来,乘了之后求和再计算贡献。

把点对拎出来是一个卷积,很容易做掉。

贡献考虑把两半边的方案数乘起来。

如果形如 \((y,y+i\bmod n)\) 的点对积之和为 \(g[i]\),有 \(i\) 个点的圆划分方案数为 \(f[i]\),前者加上强制连接 \((1,n)\) 的方案数为 \(t[i]\),那么答案为:

\[\frac{\sum_{i=1}^{n-1}g[i]t[i+1]t[n-i+1]}{4f[n]} \]

容易得到 \(2t[i]=f[i]\),那么:

\[\frac{\sum_{i=1}^{n-1}g[i]f[i+1]f[n-i+1]}{8f[n]} \]

\(g\) 很容易求得,考虑 \(f\)

容易发现,\(f\) 相当于计算序列上若干条线段互不“相交”的方案数。容易发现不“相交”只有两种可能:包含或两条线段中间夹着空格。

我们直接考虑 GF。

容易写出 DP:

\[f[n]=2f[n-1]+\sum_{i=2}^{n-1}f[i]f[n-i] \]

下面重新定义新的 \(f[n]\) 为旧的 \(f[n+1]\)

\[f[n]=2f[n-1]+\sum_{i=1}^{n-1}f[i]f[n-i] \]

\[F(x)=2xF(x)+F^2(x)-2F(x)+2 \]

\[F(x)=\frac{3-2x\pm\sqrt{4x^2-12x+1}}{2} \]

然后我们知道 \(F(0)=1\),所以试一下:

\[\frac{3+\sqrt{1}}{2}=2,\frac{3-\sqrt{1}}{2}=1 \]

所以应该是 \(F(x)=\frac{3-2x-\sqrt{4x^2-12x+1}}{2}\)

如何求出 \(F(x)\)?我们实际上只需要求出 \(\sqrt{4x^2-12x+1}\)

\(H(x)=\sqrt{4x^2-12x+1}\),然后求导列一个 ODE:

\[H'(x)=\frac{4x-6}{\sqrt{4x^2-12x+1}} \]

\[H(x)=\frac{4x^2-12x+1}{4x-6}\times H'(x) \]

\[(4x-6)H(x)=(4x^2-12x+1)H'(x) \]

\[4H[n-1]-6H[n]=4(n-1)H[n-1]-12nH[n]+(n+1)H[n+1] \]

\[H[n+1]=\frac{(12n-6)H[n]-4(n-2)H[n-1]}{n+1} \]

递推即可。

#include<cstdio>
typedef unsigned ui;
const ui M=1<<19|1,G=3,mod=998244353;
ui n,f[M],g[M],c[M];
inline ui pow(ui a,ui b=mod-2){
	ui ans(1);for(;b;b>>=1,a=1ull*a*a%mod)if(b&1)ans=1ull*ans*a%mod;return ans;
}
inline ui Add(const ui&a,const ui&b){
	return a+b>=mod?a+b-mod:a+b;
}
inline ui Del(const ui&a,const ui&b){
	return b>a?a-b+mod:a-b;
}
inline void swap(ui&a,ui&b){
	ui c=a;a=b;b=c;
}
inline void DFT(ui*f,const ui&n){
	static ui W[M];
	for(ui len=n>>1;len>=1;len>>=1){
		const ui&w1=pow(G,(mod-1>>1)/len);W[0]=1;W[1]=w1;
		for(ui i=2;i<len;++i)W[i]=1ull*W[i-1]*w1%mod;
		for(ui k=0;k<n;k+=len<<1){
			ui*w=W,*fl=f+(k),*fr=f+(k|len);
			for(ui i=0;i<len;++i){
				const ui x=*fl,y=*fr;
				*fl++=Add(x,y);*fr++=1ull**w++*Del(x,y)%mod;
			}
		}
	}
}
inline void IDFT(ui*f,const ui&n){
	static ui W[M];
	for(ui len=1;len<n;len<<=1){
		const ui&w1=pow(G,(mod-1>>1)/len);W[0]=1;W[1]=w1;
		for(ui i=2;i<len;++i)W[i]=1ull*W[i-1]*w1%mod;
		for(ui k=0;k<n;k+=len<<1){
			ui*w=W,*fl=f+(k),*fr=f+(k|len);
			for(ui i=0;i<len;++i){
				const ui x=*fl,y=1ull**w++**fr%mod;
				*fl++=Add(x,y);*fr++=Del(x,y);
			}
		}
	}
	const ui&inv=pow(n);
	for(ui i=1;(i<<1)<n;++i)swap(f[i],f[n-i]);
	for(ui i=0;i<n;++i)f[i]=1ull*f[i]*inv%mod;
}
signed main(){
	ui len(1),ans(0);
	scanf("%u",&n);c[0]=1;c[1]=1;
	for(ui i=2;i<n;++i)c[i]=1ull*(mod-mod/i)*c[mod%i]%mod;
	c[0]=1;c[1]=mod-6;
	for(ui i=2;i<n;++i)c[i]=((12ull*i-18)*c[i-1]+(mod+12-4ull*i)*c[i-2])%mod*c[i]%mod;
	for(ui i=0;i<n;++i)c[i]=mod-c[i];c[0]=(c[0]+3)%mod;c[1]=(c[1]-2)%mod;{
		const ui&inv=mod+1>>1;
		for(ui i=0;i<=n;++i)c[i]=1ull*c[i]*inv%mod;
	}
	for(ui i=0;i<n;++i)scanf("%u",f+i),g[i]=g[n+i]=f[i];
	for(ui i=0;(i<<1|1)<n;++i)swap(f[i],f[n-i-1]);
	while(len<n*3)len<<=1;
	DFT(f,len);DFT(g,len);
	for(ui i=0;i<len;++i)f[i]=1ull*f[i]*g[i]%mod;
	IDFT(f,len);
	for(ui i=1;i<n;++i)ans=(ans+1ull*c[i]*c[n-i]%mod*f[n+i-1])%mod;
	printf("%u",1ull*ans*pow(8ull*c[n-1]%mod)%mod);
}
posted @ 2022-03-04 14:58  Prean  阅读(14)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};