BM

这篇写的挺好的,就是代码有点误导人

那个构造算一下发现是对的

好吧详细说一下

流程luogu一搜一大把,这里就只补一下构造为什么是对的

假设\(Rw\)处的递推数组为\(b\),长度为\(l\),当前讨论到第\(n\)个数。

我们构造递推数组\(a\),长度为\(n-w-1+l\)

\[a_i=\begin {cases} 0(i\leq n-w-2)\\ 1(i=n-w-1)\\ -b_{i-(n-w-1)}(i\geq n-w)\\ \end {cases} \]

\(f_x:\sum_{i}f_{x-i}b_i=f_{x-(n-w-1)}-\sum_{1\leq i\leq l}a_i*f_{x-(n-w-1)-i}\)

\(n-w+l\leq x<n\)时,原式值为0

\(x=n\)时,原式即为\(\Delta_w\)

#include <bits/stdc++.h>
#define MOD 998244353
using namespace std;
inline int add(int a,int b)
{a+=b;return a>=MOD?a-MOD:a;}
inline int sub(int a,int b)
{a-=b;return a<0?a+MOD:a;}
inline int mul(int a,int b)
{return 1ll*a*b%MOD;}
int ksm(int a,int b)
{
	int ans=1;
	for(;b;b>>=1,a=mul(a,a))
		if(b&1)ans=mul(ans,a);
	return ans;
}
#define Vec vector<int>
Vec BM(const Vec&a)
{
	Vec ret,rw;
	int delw=-1,w=-1;
	for(int i=1;i<=(int)a.size();i++){
		int del=a[i-1];
		for(int j=0;j<(int)ret.size();j++)
			del=sub(del,mul(ret[j],a[i-j-2]));
		if(!del)continue;
		if(!ret.size()){
			w=i-1;
			delw=del;
			ret.resize(i);
			continue;
		}
		Vec rem=ret;
		int va=mul(ksm(delw,MOD-2),del);
		if(ret.size()<rw.size()+i-w-1)ret.resize(rw.size()+i-w-1);
		ret[i-w-2]=add(ret[i-w-2],va);
		for(int j=0;j<(int)rw.size();j++)
			ret[i-w+j-1]=sub(ret[i-w+j-1],mul(rw[j],va));
		if((int)rem.size()-(i-1)<(int)rw.size()-w){
			w=i-1;
			rw=rem;
			delw=del;
		}
	}
	return ret;
}
int main()
{
	int n;
	scanf("%d",&n);
	Vec ini(n);
	for(int i=0;i<n;i++)
		scanf("%d",&ini[i]);
	Vec als=BM(ini);
	for(int v:als)printf("%d ",v);puts("");
	return 0;
}
posted @ 2020-07-14 21:31  蒟蒻小果冻  阅读(14)  评论(0编辑  收藏