闲话 23.2.12

闲话

今日推歌:玛德琳娜电塔 - by 纯白 p feat. 洛天依 / warma
虽然曲子是活泼积极的感觉,但内核却是深深的悲剧与无助
感觉很多歌曲都会采用这种做法呢,比如说阿良良老师的《春风来》。

我等春风吹过来 梨花朵朵盛开
水暖春江 笑满园

对未来的美好幻想很多时候隐含着对可见未来和现实的哀叹。
这么一想 感觉《边城》的结局又多了些悲剧色彩。
《春风来》真的很好听。

说句题外话,阿良良老师的专辑《奇爱人生》的英文名是 Love Elegia,这里 Elegia 取哀歌义。

奇怪题

考虑一张 \(n\) 个点的无向图 \(G\) 以及它的邻接矩阵 \(g\),如果 \(i,j\) 之间有边那么 \(g_{i,j}=1\),否则 \(g_{i,j}=0\)

下面是一个正常的 Floyd 算法:

void Floyd(int n) {
	for (int k = 1; k <= n; k++)
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				if (i != j)
					g[i][j] |= g[i][k] && g[k][j];
}

下面是一个带参数 \(m\) 的 Super Brilliant 的 Floyd 算法:

void sbFloyd(int n,int m) {
	for (int k = 1; k <= n - m; k++)
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				if (i != j)
					g[i][j] |= g[i][k] && g[k][j];
}

给定 \(n, m\),计数有多少张有标号的 \(n\) 个点的图满足邻接矩阵扔进上面两种 Floyd 算法后得到的结果相同。


我们令 \(1\sim n - m\) 的点是黑点,剩下的点是白点。
这样我们可以描述题设为:图的任意连通块内两个点都可以找到一条除端点外只包含黑点的路径。

观察可以发现,只有白点的连通块必定是团;有黑点的连通块对应黑点的导出子图必定联通,每个白点都必定和一个黑点联通。
我们记 \(f(n, m)\)\(n\) 个黑点 \(m\) 个白点的图的方案数,大小为 \(i\) 的简单无向联通图的方案数是 \(g(n)\),则可以通过强制标号和讨论连通块种类(只有白点/有黑点)的方式得到转移:

\[\begin{aligned} f(n, m) =& \sum_{i = 1}^m f(n - i, m - i) \binom{m - 1}{i - 1} + \\ & \sum_{i = 1}^{n - m} \sum_{j = 1}^m f(n - i - j, m - j) \binom{n - m}{i} \binom{m - 1}{j - 1} g(i)(2^i - 1)^j2^{j(j - 1) / 2}\end{aligned}\]

时间复杂度 \(O(n^4)\)

这就是极限了吗?生成函数告诉你,不是的。

我们下面首先讨论一个大小的连通块的方案。只有白点的连通块对一个大小只有一种方案,不是重点。

对于黑点,我们需要分别描述各部分。假设大小为 \(i\) 的简单无向联通图的方案数是 \(f_i\),这可以通过有标号 \(\text{Set}\) 的逆得到。
我们假设有 \(i\) 个黑点,\(j\) 个白点,则联通的方案是 \(f_i\),每个白点向黑点连边的方案是 \((2^i - 1)^j\),白点间互相联通的方案是 \(2^{j(j - 1) / 2}\)

可以发现我们现在可以描述一个连通块的组合结构了,对这个结构作有标号 \(\text{Set}\) 构造即得答案。答案即为

\[\left[\frac{x^{n - m}y^m}{(n - m)! m!}\right] \exp\left( e^y - 1 + \sum_{i, j\ge 0} f_i(2^i - 1)^j2^{j(j - 1) / 2}\frac{x^iy^j}{i!j!} \right) \]

这个大概可以通过直接操作 bgf 的系数并牛顿迭代得到 \(O(n^2 \log n)\) 的复杂度。

写了一半
#include <bits/stdc++.h>
using namespace std;
#define inline __attribute__((__gnu_inline__, __always_inline__, __artificial__)) inline
using pii = pair<int,int>; using vi = vector<int>; using vp = vector<pii>; using ll = long long; 
using ull = unsigned long long; using db = double; using ld = long double; using lll = __int128_t;
template<typename T1, typename T2> T1 max(T1 a, T2 b) { return a > b ? a : b; }
template<typename T1, typename T2> T1 min(T1 a, T2 b) { return a < b ? a : b; }
#define multi int T; cin >> T; while ( T -- )
#define timer cerr << 1. * clock() / CLOCKS_PER_SEC << '\n';
#define iot ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define rep(i,s,t) for (register int i = (s), i##_ = (t) + 1; i < i##_; ++ i)
#define pre(i,s,t) for (register int i = (s), i##_ = (t) - 1; i > i##_; -- i)
#define eb emplace_back
#define pb pop_back
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fll;

#pragma GCC target ("avx2","sse4.2","fma")
#include <immintrin.h>
namespace __POLY__ { 
	const int mod = 998244353, proot = 3;
	typedef int i32;typedef unsigned int u32;typedef long long i64;typedef unsigned long long u64;typedef vector<i32>vi32;typedef vector<u32>vu32;typedef vector<i64>vi64;typedef vector<u64>vu64;namespace math{template<typename T=int>inline T qp(i64 x,int y,i64 ans=1){for(y<0?y+=mod-1:0;y;y>>=1,x=x*x%mod)y&1?ans=ans*x%mod:0;return ans;}inline constexpr int lg(u32 x){return x==0?-1:((int)sizeof(int)*__CHAR_BIT__-1-__builtin_clz(x));}inline u32 fst_mul(u32 x,u64 p,u64 q){return x*p-(q*x>>32)*mod;}const u32 modm2=mod+mod;namespace basic_math{vu32 __fac({1,1}),__ifc({1,1}),__inv({0,1});inline void __prep(int n){static int i=2;if(i<n)for(__fac.resize(n),__ifc.resize(n),__inv.resize(n);i<n;i++)__fac[i]=1ll*i*__fac[i-1]%mod,__inv[i]=1ll*(mod-mod/i)*__inv[mod%i]%mod,__ifc[i]=1ll*__inv[i]*__ifc[i-1]%mod;}inline u32 gfac(u32 x){return __prep(x+1),__fac[x];}inline u32 gifc(u32 x){return __prep(x+1),__ifc[x];}inline u32 ginv(u32 x){return __prep(x+1),__inv[x];}inline u32 gC(u32 n,u32 m){if(n<m)return 0;return 1ll*gfac(n)*gifc(m)%mod*gifc(n-m)%mod;}}namespace cipolla{u32 I=0;struct cpl{u32 x,y;cpl(u32 _x=0,u32 _y=0):x(_x),y(_y){}inline cpl operator*(const cpl&a)const{return cpl((1ull*x*a.x+1ull*I*y%mod*a.y)%mod,(1ull*x*a.y+1ull*y*a.x)%mod);}};inline cpl cplpow(cpl a,int y,cpl b=cpl(1,0)){for(;y;y>>=1,a=a*a)if(y&1)b=b*a;return b;}inline u32 isqrt(u32 x){static mt19937 rnd(998244353);if(mod==2||!x||x==1)return x;u32 a=0;do{a=rnd()%mod;}while(qp((1ull*a*a+mod-x)%mod,mod>>1)!=mod-1);I=(1ll*a*a+mod-x)%mod;a=cplpow(cpl(a,1),(mod+1)>>1).x;return min(a,mod-a);}}using basic_math::gfac;using basic_math::gifc;using basic_math::ginv;using cipolla::isqrt;}
	namespace polynomial{const int maxbit=21;using math::gfac;using math::gifc;using math::ginv;using math::lg;using math::qp;namespace fast_number_theory_transform{using math::fst_mul;using math::modm2;u32 pool[(1<<23)*4]__attribute__((aligned(64))),*ptr=pool;u32*p0[(1<<23)],*p1[(1<<23)],*q0[(1<<23)],*q1[(1<<23)];__attribute__((always_inline))inline void bit_flip(u32*p,int t){for(int i=0,j=0;i<t;++i){if(i>j)swap(p[i],p[j]);for(int l=t>>1;(j^=l)<l;l>>=1);}}void prep(int n){static int t=1;for(;t<n;t<<=1){int g=qp(3,(mod-1)/(t*2));u32*p,*q;p=p0[t]=ptr;ptr+=max(t,16);p[0]=1;for(int m=1;m<t;++m)p[m]=p[m-1]*(ull)g%u32(mod);bit_flip(p,t);q=q0[t]=ptr;ptr+=max(t,16);for(int i=0;i<t;++i)q[i]=(ull(p[i])<<32)/mod;g=qp(g,mod-2);p=p1[t]=ptr;ptr+=max(t,16);p[0]=1;for(int m=1;m<t;++m)p[m]=p[m-1]*(ull)g%u32(mod);bit_flip(p,t);q=q1[t]=ptr;ptr+=max(t,16);for(int i=0;i<t;++i)q[i]=(ull(p[i])<<32)/mod;}}typedef unsigned long long ull;__attribute__((always_inline))inline u32 my_mul(u32 a,u32 b,u32 c){return b*(ull)a-((ull(a)*c)>>32)*ull(998244353);}__attribute__((always_inline))inline __m128i my_mullo_epu32(const __m128i&a,const __m128i&b){return _mm_mullo_epi32(a,b);}__attribute__((always_inline))inline __m128i my_mulhi_epu32(const __m128i&a,const __m128i&b){__m128i a13=_mm_shuffle_epi32(a,0xF5);__m128i b13=_mm_shuffle_epi32(b,0xF5);__m128i prod02=_mm_mul_epu32(a,b);__m128i prod13=_mm_mul_epu32(a13,b13);__m128i prod01=_mm_unpacklo_epi32(prod02,prod13);__m128i prod23=_mm_unpackhi_epi32(prod02,prod13);__m128i prod=_mm_unpackhi_epi64(prod01,prod23);return prod;}void ntt(u32*__restrict__ x,int bit){int n=1<<bit,t=n;prep(n);for(int m=1;m<n;m<<=1){t>>=1;u32*__restrict__ p=p0[m];u32*__restrict__ q=q0[m];if(t==1){u32*xa=x,*xb=x+t;for(int i=0;i<m;++i,xa+=t+t,xb+=t+t)for(int j=0;j<t;++j){u32 u=xa[j]-(xa[j]>=modm2)*modm2;u32 v=my_mul(xb[j],p[i],q[i]);xa[j]=u+v;xb[j]=u-v+modm2;}}else if(t==2){u32*xa=x,*xb=x+t;for(int i=0;i<m;++i,xa+=t+t,xb+=t+t)for(int j=0;j<t;++j){u32 u=xa[j]-(xa[j]>=modm2)*modm2;u32 v=my_mul(xb[j],p[i],q[i]);xa[j]=u+v;xb[j]=u-v+modm2;}}else if(t==4){u32*xa=x,*xb=x+t;for(int i=0;i<m;++i,xa+=t+t,xb+=t+t){const __m128i p4=_mm_set1_epi32(p[i]),q4=_mm_set1_epi32(q[i]),mm=_mm_set1_epi32(mod+mod),m0=_mm_set1_epi32(0),m1=_mm_set1_epi32(mod);for(int j=0;j<t;j+=4){__m128i u=_mm_loadu_si128((__m128i*)(xa+j));u=_mm_sub_epi32(u,_mm_and_si128(_mm_or_si128(_mm_cmpgt_epi32(u,mm),_mm_cmpgt_epi32(m0,u)),mm));__m128i v=_mm_loadu_si128((__m128i*)(xb+j));v=_mm_sub_epi32(my_mullo_epu32(v,p4),my_mullo_epu32(my_mulhi_epu32(v,q4),m1));_mm_storeu_si128((__m128i*)(xa+j),_mm_add_epi32(u,v));_mm_storeu_si128((__m128i*)(xb+j),_mm_add_epi32(_mm_sub_epi32(u,v),mm));}}}else{u32*xa=x,*xb=x+t;for(int i=0;i<m;++i,xa+=t+t,xb+=t+t){const __m128i p4=_mm_set1_epi32(p[i]),q4=_mm_set1_epi32(q[i]),mm=_mm_set1_epi32(mod+mod),m0=_mm_set1_epi32(0),m1=_mm_set1_epi32(mod);for(int j=0;j<t;j+=8){__m128i u0=_mm_loadu_si128((__m128i*)(xa+j));__m128i u1=_mm_loadu_si128((__m128i*)(xa+j+4));__m128i v0=_mm_loadu_si128((__m128i*)(xb+j));__m128i v1=_mm_loadu_si128((__m128i*)(xb+j+4));u0=_mm_sub_epi32(u0,_mm_and_si128(_mm_or_si128(_mm_cmpgt_epi32(u0,mm),_mm_cmpgt_epi32(m0,u0)),mm));u1=_mm_sub_epi32(u1,_mm_and_si128(_mm_or_si128(_mm_cmpgt_epi32(u1,mm),_mm_cmpgt_epi32(m0,u1)),mm));v0=_mm_sub_epi32(my_mullo_epu32(v0,p4),my_mullo_epu32(my_mulhi_epu32(v0,q4),m1));v1=_mm_sub_epi32(my_mullo_epu32(v1,p4),my_mullo_epu32(my_mulhi_epu32(v1,q4),m1));_mm_storeu_si128((__m128i*)(xa+j),_mm_add_epi32(u0,v0));_mm_storeu_si128((__m128i*)(xa+j+4),_mm_add_epi32(u1,v1));_mm_storeu_si128((__m128i*)(xb+j),_mm_add_epi32(_mm_sub_epi32(u0,v0),mm));_mm_storeu_si128((__m128i*)(xb+j+4),_mm_add_epi32(_mm_sub_epi32(u1,v1),mm));}}}}for(int i=0;i<n;++i)x[i]-=(x[i]>=modm2)*modm2,x[i]-=(x[i]>=u32(mod))*u32(mod);}void intt(u32*__restrict__ x,int bit){int n=1<<bit,t=1;prep(n);for(int m=(n>>1);m;m>>=1){u32*__restrict__ p=p1[m];u32*__restrict__ q=q1[m];if(t==1){u32*xa=x,*xb=x+t;for(int i=0;i<m;++i,xa+=t+t,xb+=t+t)for(int j=0;j<t;++j){u32 u=xa[j],v=xb[j];xa[j]=u+v-(u+v>=modm2)*modm2;xb[j]=my_mul(u-v+modm2,p[i],q[i]);}}else if(t==2){u32*xa=x,*xb=x+t;for(int i=0;i<m;++i,xa+=t+t,xb+=t+t)for(int j=0;j<t;++j){u32 u=xa[j],v=xb[j];xa[j]=u+v-(u+v>=modm2)*modm2;xb[j]=my_mul(u-v+modm2,p[i],q[i]);}}else if(t==4){u32*xa=x,*xb=x+t;for(int i=0;i<m;++i,xa+=t+t,xb+=t+t){const __m128i p4=_mm_set1_epi32(p[i]),q4=_mm_set1_epi32(q[i]),mm=_mm_set1_epi32(mod+mod),m0=_mm_set1_epi32(0),m1=_mm_set1_epi32(mod);for(int j=0;j<t;j+=4){__m128i u=_mm_loadu_si128((__m128i*)(xa+j));__m128i v=_mm_loadu_si128((__m128i*)(xb+j));__m128i uv=_mm_add_epi32(u,v);_mm_storeu_si128((__m128i*)(xa+j),_mm_sub_epi32(uv,_mm_and_si128(_mm_or_si128(_mm_cmpgt_epi32(uv,mm),_mm_cmpgt_epi32(m0,uv)),mm)));uv=_mm_add_epi32(_mm_sub_epi32(u,v),mm);_mm_storeu_si128((__m128i*)(xb+j),_mm_sub_epi32(my_mullo_epu32(uv,p4),my_mullo_epu32(my_mulhi_epu32(uv,q4),m1)));}}}else{u32*xa=x,*xb=x+t;for(int i=0;i<m;++i,xa+=t+t,xb+=t+t){const __m128i p4=_mm_set1_epi32(p[i]),q4=_mm_set1_epi32(q[i]),mm=_mm_set1_epi32(mod+mod),m0=_mm_set1_epi32(0),m1=_mm_set1_epi32(mod);for(int j=0;j<t;j+=8){__m128i u0=_mm_loadu_si128((__m128i*)(xa+j));__m128i u1=_mm_loadu_si128((__m128i*)(xa+j+4));__m128i v0=_mm_loadu_si128((__m128i*)(xb+j));__m128i v1=_mm_loadu_si128((__m128i*)(xb+j+4));__m128i uv0=_mm_add_epi32(u0,v0);__m128i uv1=_mm_add_epi32(u1,v1);_mm_storeu_si128((__m128i*)(xa+j),_mm_sub_epi32(uv0,_mm_and_si128(_mm_or_si128(_mm_cmpgt_epi32(uv0,mm),_mm_cmpgt_epi32(m0,uv0)),mm)));_mm_storeu_si128((__m128i*)(xa+j+4),_mm_sub_epi32(uv1,_mm_and_si128(_mm_or_si128(_mm_cmpgt_epi32(uv1,mm),_mm_cmpgt_epi32(m0,uv1)),mm)));uv0=_mm_add_epi32(_mm_sub_epi32(u0,v0),mm);uv1=_mm_add_epi32(_mm_sub_epi32(u1,v1),mm);_mm_storeu_si128((__m128i*)(xb+j),_mm_sub_epi32(my_mullo_epu32(uv0,p4),my_mullo_epu32(my_mulhi_epu32(uv0,q4),m1)));_mm_storeu_si128((__m128i*)(xb+j+4),_mm_sub_epi32(my_mullo_epu32(uv1,p4),my_mullo_epu32(my_mulhi_epu32(uv1,q4),m1)));}}}t<<=1;}u32 rn=qp(n,mod-2);for(int i=0;i<n;++i)x[i]=x[i]*(ull)rn%mod;}}using fast_number_theory_transform::intt;using fast_number_theory_transform::ntt;
	struct poly{vu32 f;template<typename _Tp=size_t,typename _Tv=u32>poly(_Tp len=1,_Tv same_val=0):f(len,same_val){}poly(const vu32&_f):f(_f){}poly(const vi32&_f){f.resize(((int)_f.size()));for(int i=0;i<((int)_f.size());i++){f[i]=_f[i]+((_f[i]>>31)&mod);}}template<typename T>poly(initializer_list<T>_f):poly(vector<T>(_f)){}template<typename T>poly(T*__first,T*__last):poly(vector<typename iterator_traits<T>::value_type>(__first,__last)){}inline operator vu32()const{return f;}inline vu32::iterator begin(){return f.begin();}inline vu32::iterator end(){return f.end();}void swap(poly&_f){f.swap(_f.f);}inline int degree()const{return f.size()-1;}inline int size()const{return f.size();}inline poly&resize(int x){return f.resize(x),*this;}inline poly&redegree(int x){return f.resize(x+1),*this;}inline void clear(){f.resize(1),f[0]=0;}inline void shrink(){int ndeg=f.size()-1;while(ndeg>0&&f[ndeg]==0)ndeg--;f.resize(ndeg+1);}inline void rev(){reverse(f.begin(),f.end());}inline poly split(int n)const{return n<=0?poly(1,1):(n<(int)f.size()?poly(f.begin(),f.begin()+n+1):poly(*this).redegree(n));}inline u32&operator[](u32 x){return f[x];}inline u32 operator[](u32 x)const{return f[x];}inline u32 get(u32 x)const{return x<f.size()?f[x]:0;}friend istream&operator>>(istream&in,poly&x){for(int i=0;i<x.f.size();i++)in>>x.f[i];return in;}friend ostream&operator<<(ostream&out,const poly&x){out<<x.f[0];for(int i=1;i<x.f.size();i++)out<<' '<<x.f[i];return out;}inline u32*data(){return f.data();}inline const u32*data()const{return f.data();}inline poly&operator+=(const poly&a){f.resize(max(f.size(),a.f.size()));for(int i=0;i<a.f.size();i++)f[i]=f[i]+a.f[i]-(f[i]+a.f[i]>=mod)*mod;return*this;}inline poly&operator-=(const poly&a){f.resize(max(f.size(),a.f.size()));for(int i=0;i<a.f.size();i++)f[i]=f[i]-a.f[i]+(f[i]<a.f[i])*mod;return*this;}inline poly&operator+=(const u32&b){f[0]=f[0]+b-mod*(f[0]+b>=mod);return*this;}inline poly&operator-=(const u32&b){f[0]=f[0]-b+mod*(f[0]<b);return*this;}inline poly operator+(const poly&a)const{return(poly(*this)+=a);}inline poly operator-(const poly&a)const{return(poly(*this)-=a);}friend inline poly operator+(u32 a,const poly&b){return(poly(1,a)+=b);}friend inline poly operator-(u32 a,const poly&b){return(poly(1,a)-=b);}friend inline poly operator+(const poly&a,u32 b){return(poly(a)+=poly(1,b));}friend inline poly operator-(const poly&a,u32 b){return(poly(a)-=poly(1,b));}inline poly operator-()const{poly _f;_f.f.resize(f.size());for(int i=0;i<_f.f.size();i++)_f.f[i]=(f[i]!=0)*mod-f[i];return _f;}inline poly amp(int k)const{poly ret(size());for(int i=0;i*k<=degree();++i)ret[i*k]=f[i];return ret;}inline poly&operator*=(const poly&a){int n=degree(),m=a.degree();if(n<16||m<16){f.resize(n+m+1);for(int i=n+m;i>=0;i--){f[i]=1ll*f[i]*a.f[0]%mod;for(int j=max(1,i-n),j_up=min(m,i);j<=j_up;j++)f[i]=(f[i]+1ll*f[i-j]*a.f[j])%mod;}return*this;}vu32 _f(a.f);int bit=lg(n+m)+1;f.resize(1<<bit);_f.resize(1<<bit);ntt(f.data(),bit);ntt(_f.data(),bit);for(int i=0;i<(1<<bit);i++)f[i]=1ll*f[i]*_f[i]%mod;intt(f.data(),bit);f.resize(n+m+1);return*this;}inline poly operator*(const poly&a)const{return(poly(*this)*=a);}template<typename T>inline friend poly operator*(const poly&a,const T&b){poly ret(a);for(int i=0;i<ret.f.size();++i)ret[i]=1ll*ret[i]*b%mod;return ret;}template<typename T>inline friend poly operator*(const T&b,const poly&a){poly ret(a);for(int i=0;i<ret.f.size();++i)ret[i]=1ll*ret[i]*b%mod;return ret;}template<typename T>inline poly&operator*=(const T&b){for(int i=0;i<f.size();++i)f[i]=1ll*f[i]*b%mod;return*this;}inline poly&operator>>=(int x){return f.resize(f.size()+x),memmove(f.data()+x,f.data(),4*(f.size()-x)),memset(f.data(),0,4*x),*this;}inline poly operator>>(int x)const{return(poly(*this)>>=x);}inline poly&operator<<=(int x){return x>=f.size()?(clear(),*this):(memmove(f.data(),f.data()+x,4*(f.size()-x)),f.resize(f.size()-x),*this);}inline poly operator<<(int x)const{return(poly(*this)<<=x);}inline poly&shiftindexwith(int x){return x>=f.size()?(memset(f.data(),0,4*f.size()),*this):(memmove(f.data(),f.data()+x,4*(f.size()-x)),memset(f.data(),0,4*x),*this);}inline poly shiftindex(int x)const{return(poly(*this).shiftindexwith(x));}inline poly inv()const;inline poly quo(const poly&g)const;inline poly operator/(const poly&g){return f.size()==1?poly(1,qp(g[0],-1,f[0])):quo(g);}inline poly&quowith(const poly&g){return f.size()==1?(f[0]=qp(g[0],-1,f[0]),*this):(*this=quo(g));}inline poly deri()const{int n=degree();poly res;res.redegree(n-1);for(int i=1;i<=n;i++)res[i-1]=1ll*f[i]*i%mod;return res;}inline poly intg(u32 C=0)const{int n=degree();poly res(1,C);res.redegree(n+1);for(int i=0;i<=n;i++)res[i+1]=1ll*ginv(i+1)*f[i]%mod;return res;}inline poly pow(u32 x,u32 modphix=-1){if(modphix==-1)modphix=x;int n=size()-1;i64 empt=0;while(empt<=n and!f[empt])++empt;if(1ll*empt*x>n)return poly(size());poly res(size());for(int i=0;i<=n-empt;++i)res[i]=f[i+empt];int val_0=res[0],inv_0=qp(val_0,mod-2),pow_0=qp(val_0,modphix);for(int i=0;i<=n-empt;++i)res[i]=1ll*res[i]*inv_0%mod;res=(res.ln()*x).exp();empt*=x;for(int i=n;i>=empt;--i)res[i]=1ll*res[i-empt]*pow_0%mod;for(int i=empt-1;i>=0;--i)res[i]=0;return res;}inline poly ivsqrt()const{int nsize=f.size(),mxb=lg(f.size()-1)+1;vu32 a(1<<mxb),_f(f);_f.resize(1<<mxb);a[0]=qp(math::isqrt(f[0]),mod-2);for(int nb=0;nb<mxb;nb++){vu32 _a(a.begin(),a.begin()+(1<<nb)),_b(_f.begin(),_f.begin()+(2<<nb));_a.resize(4<<nb);_b.resize(4<<nb);ntt(_a.data(),nb+2);ntt(_b.data(),nb+2);for(int i=0;i<(4<<nb);i++)_a[i]=1ull*(mod-_a[i])*_a[i]%mod*_a[i]%mod*_b[i]%mod,_a[i]=(_a[i]+(_a[i]&1)*mod)>>1;intt(_a.data(),nb+2);memcpy(a.data()+(1<<nb),_a.data()+(1<<nb),4<<nb);}return a.resize(nsize),a;}inline poly sqrt()const{if(f.size()==1)return poly(1,math::isqrt(f[0]));if(f.size()==2&&f[0]==1)return poly(vector<int>{1,(int)(1ll*f[1]*(mod+1)/2%mod)});int nsize=f.size(),mxb=lg(nsize-1)+1;vu32 a(1<<mxb),_f(f),_b;_f.resize(1<<mxb);a[0]=qp(math::isqrt(f[0]),mod-2);for(int nb=0;nb<mxb-1;nb++){vu32 _a(a.begin(),a.begin()+(1<<nb));_b=vu32(_f.begin(),_f.begin()+(2<<nb));_a.resize(4<<nb);_b.resize(4<<nb);ntt(_a.data(),nb+2);ntt(_b.data(),nb+2);for(int i=0;i<(4<<nb);i++)_a[i]=1ull*(mod-_a[i])*_a[i]%mod*_a[i]%mod*_b[i]%mod,_a[i]=(_a[i]+(_a[i]&1)*mod)>>1;intt(_a.data(),nb+2);memcpy(a.data()+(1<<nb),_a.data()+(1<<nb),4<<nb);}ntt(a.data(),mxb);vu32 _a(a);for(int i=0;i<(1<<mxb);i++)a[i]=1ll*a[i]*_b[i]%mod;intt(a.data(),mxb),memset(a.data()+(1<<(mxb-1)),0,2<<mxb);vu32 g0(a);ntt(a.data(),mxb),ntt(_f.data(),mxb);for(int i=0;i<(1<<mxb);i++)a[i]=(1ll*a[i]*a[i]+mod-_f[i])%mod*(mod-_a[i])%mod,a[i]=(a[i]+(a[i]&1)*mod)>>1;intt(a.data(),mxb);memcpy(g0.data()+(1<<(mxb-1)),a.data()+(1<<(mxb-1)),2<<mxb);return g0;}inline poly czt(int c,int m)const{poly ret(f);int inv=qp(c,mod-2),n=ret.size();ret.resize(m);poly F(n),G(n+m);for(int i=0,p1=1,p2=1;i<n;++i){F[n-i-1]=1ll*ret[i]*p1%mod;i&&(p2=1ll*p2*inv%mod,p1=1ll*p1*p2%mod,true);}for(int i=0,p1=1,p2=1;i<n+m;++i){G[i]=p1;i&&(p2=1ll*p2*c%mod,p1=1ll*p1*p2%mod,true);}F=F*G;for(int i=0,p1=1,p2=1;i<m;++i){ret[i]=1ll*F[i+n-1]*p1%mod;i&&(p2=1ll*p2*inv%mod,p1=1ll*p1*p2%mod,true);}return ret;}inline poly ChirpZ(int c,int m)const{return czt(c,m);}inline poly shift(int c)const{c%=mod;c=c+(c<0)*mod;if(c==0)return*this;poly A(size()),B(size()),ret(size());for(int i=0;i<size();++i)A[size()-i-1]=1ll*f[i]*gfac(i)%mod;for(int i=0,pc=1;i<size();++i,pc=1ll*pc*c%mod)B[i]=1ll*pc*gifc(i)%mod;A*=B;A.resize(size());for(int i=0;i<size();++i)ret[i]=1ll*A[size()-i-1]*gifc(i)%mod;return ret;}inline poly fdt()const{poly F(*this),E(size());for(int i=0;i<size();++i)E[i]=gifc(i);F*=E;F.resize(size());for(int i=0;i<size();++i)F[i]=1ll*F[i]*gfac(i)%mod;return F;}inline poly ifdt()const{poly F(*this),E(size());for(int i=0;i<size();++i)F[i]=1ll*F[i]*gifc(i)%mod;for(int i=0;i<size();++i)if(i&1)E[i]=mod-gifc(i);else E[i]=gifc(i);return(F*E).split(degree());}inline poly ln()const;inline poly exp()const;inline poly eval(int n,poly a)const;inline poly intp(int n,const poly&x,const poly&y);inline poly sin()const{int omega_4=qp(proot,(mod-1)>>2);poly F=((*this)*omega_4).exp();return qp(omega_4*2,mod-2)*(F-F.inv());}inline poly cos()const{int omega_4=qp(proot,(mod-1)>>2);poly F=((*this)*omega_4).exp();return qp(2,mod-2)*(F+F.inv());}inline poly tan()const{return sin()/cos();}inline poly asin()const{poly A=deri(),B=(*this)*(*this);B.resize(size());B=(1-B).ivsqrt();return(A*B).intg().split(degree());}inline poly acos()const{poly A=(mod-1)*deri(),B=(*this)*(*this);B.resize(size());B=(1-B).ivsqrt();return(A*B).intg().split(degree());}inline poly atan()const{poly A=deri(),B=1+(*this)*(*this);B.resize(size());B=B.inv();return(A*B).intg().split(degree());}};inline poly operator""_p(const char*str,size_t len){poly ans(2);int sgn=1,phase=0,coeff=0,touch=0;i32 cnum=0;auto clean=[&](){if(sgn==-1)coeff=(coeff==0?coeff:mod-coeff);if(phase==-1)ans[1]+=coeff;else if(phase==0)ans[0]+=(int)cnum;else if(phase==1)ans.resize(max(cnum+1,ans.size())),ans[cnum]+=coeff;else assert(0);phase=cnum=touch=0;};for(int i=0;i<(int)len;++i){if(str[i]=='+')clean(),sgn=1;else if(str[i]=='-')clean(),sgn=-1;else if('0'<=str[i]and str[i]<='9'){assert(phase==0||phase==1);if(phase==0)touch=1,cnum=(10ll*cnum+str[i]-48)%mod;else cnum=10ll*cnum+str[i]-48,assert(cnum<1e8);}else if(str[i]=='x'){while(str[i+1]==' ')++i;assert(str[i+1]=='^'||str[i+1]=='+'||str[i+1]=='-'||str[i+1]==0);phase=-1;coeff=touch?cnum:1;cnum=0;}else if(str[i]=='^'){assert(phase==-1);phase=1;}}clean();return ans;}
	namespace __semiconvol__{const int logbr=4,br=1<<logbr,maxdep=(maxbit-1)/logbr+1,__bf=6,bf=max(__bf,logbr-1),pbf=1<<bf;inline void src(poly&f,const poly&g,const function<void(const int&,poly&,const poly&)>&relax){int nsize=g.size(),mxb=lg(nsize-1)+1;math::basic_math::__prep(mxb);f.resize(1<<mxb);vu32 __prentt[maxdep][br];for(int i=0,k=mxb;k>bf;k-=logbr,i++){for(int j=0;j<br-1;j++){if((j<<(k-logbr))>=nsize)break;__prentt[i][j].resize(2<<(k-logbr));int nl=(j<<(k-logbr)),nr=min(((j+2)<<(k-logbr)),nsize)-nl;memcpy(__prentt[i][j].data(),g.data()+nl,nr*4);ntt(__prentt[i][j].data(),k-logbr+1);}}function<void(int,int,int)>__div=[&f,&__prentt,&g,&mxb,&__div,&relax](int x,int l,int r){if(r-l<=pbf){for(int i=l;i<r;i++){relax(i,f,g);if(i+1<r)for(int j=i+1;j<r;j++)f[j]=(f[j]+1ll*f[i]*g[j-i])%mod;}return;}int nbit=mxb-logbr*(x+1),nbr=0;vu32 __tmp[br];while(l+(nbr<<nbit)<r){__tmp[nbr].resize(2<<nbit);nbr++;}for(int i=0;i<nbr;i++){if(i!=0){intt(__tmp[i].data(),nbit+1);for(int j=0;j<(1<<nbit);j++){u32&x=f[l+(i<<nbit)+j],&y=__tmp[i][j+(1<<nbit)];x=x+y-(x+y>=mod)*mod,y=0;}}__div(x+1,l+(i<<nbit),min(l+((i+1)<<nbit),r));if(i!=nbr-1){memcpy(__tmp[i].data(),f.data()+l+(i<<nbit),4<<nbit);ntt(__tmp[i].data(),nbit+1);for(int j=i+1;j<nbr;j++)for(int k=0;k<(2<<nbit);k++)__tmp[j][k]=(__tmp[j][k]+1ll*__tmp[i][k]*__prentt[x][j-i-1][k])%mod;}}};__div(0,0,nsize);f.resize(nsize);}}using __semiconvol__::src;inline poly poly::ln()const{poly ret;src(ret,*this,[&](const int&i,poly&f,const poly&g){if(i==0)f[i]=0;else f[i]=(1ll*g[i]*i+mod-f[i])%mod;});pre(i,degree(),1)ret[i]=1ll*ginv(i)*ret[i]%mod;return ret;}inline poly poly::exp()const{poly ret,tmp(*this);rep(i,0,degree())tmp[i]=1ll*tmp[i]*i%mod;src(ret,tmp,[&](const int&i,poly&f,const poly&g){if(i==0)f[i]=1;else f[i]=1ll*f[i]*ginv(i)%mod;});return ret;}inline poly poly::inv()const{poly ret,tmp(*this);int ivf0=qp(f[0],mod-2);tmp[0]=0;src(ret,tmp,[&](const int&i,poly&f,const poly&g){if(i==0)f[i]=ivf0;else f[i]=1ll*ivf0*(mod-f[i])%mod;});return ret;}inline poly poly::quo(const poly&g)const{using namespace __semiconvol__;int nsize=f.size(),mxb=lg(nsize-1)+1;vu32 res(1<<mxb),__prentt[maxdep][br],_f(g.f);u32 ivf0=qp(_f[0],-1);_f[0]=0;_f.resize(nsize);for(int i=0,k=mxb;k>bf;k-=logbr,i++){for(int j=0;j<br-1;j++){if((j<<(k-logbr))>=nsize)break;__prentt[i][j].resize(2<<(k-logbr));int nl=(j<<(k-logbr)),nr=min(((j+2)<<(k-logbr)),nsize)-nl;memcpy(__prentt[i][j].data(),_f.data()+nl,nr*4);ntt(__prentt[i][j].data(),k-logbr+1);}}function<void(int,int,int)>__div=[=,&res,&__prentt,&_f,&mxb,&__div,&ivf0](int x,int l,int r){if(r-l<=pbf){for(int i=l;i<r;i++){res[i]=1ll*ivf0*(i==0?f[0]:f[i]+mod-res[i])%mod;if(i+1<r){u64 __tmp=res[i];for(int j=i+1;j<r;j++)res[j]=(res[j]+__tmp*_f[j-i])%mod;}}return;}int nbit=mxb-logbr*(x+1),nbr=0;vu32 __tmp[br];while(l+(nbr<<nbit)<r){__tmp[nbr].resize(2<<nbit);nbr++;}for(int i=0;i<nbr;i++){if(i!=0){intt(__tmp[i].data(),nbit+1);for(int j=0;j<(1<<nbit);j++){u32&x=res[l+(i<<nbit)+j],&y=__tmp[i][j+(1<<nbit)];x=x+y-(x+y>=mod)*mod,y=0;}}__div(x+1,l+(i<<nbit),min(l+((i+1)<<nbit),r));if(i!=nbr-1){memcpy(__tmp[i].data(),res.data()+l+(i<<nbit),4<<nbit);ntt(__tmp[i].data(),nbit+1);for(int j=i+1;j<nbr;j++)for(int k=0;k<(2<<nbit);k++)__tmp[j][k]=(__tmp[j][k]+1ll*__tmp[i][k]*__prentt[x][j-i-1][k])%mod;}}};__div(0,0,nsize);return res.resize(nsize),res;}
	namespace __multipoint_operation__{vector<poly>__Q;poly _E_Mul(poly A,poly B){int n=A.size(),m=B.size();B.rev();B=A*B;for(int i=0;i<n;++i)A[i]=B[i+m-1];return A;}void _E_Init(int p,int l,int r,poly&a){if(l==r){__Q[p].resize(2);__Q[p][0]=1,__Q[p][1]=(a[l]?mod-a[l]:a[l]);return;}int mid=l+r>>1;_E_Init(p<<1,l,mid,a),_E_Init(p<<1|1,mid+1,r,a);__Q[p]=__Q[p<<1]*__Q[p<<1|1];}void _E_Calc(int p,int l,int r,const poly&F,poly&g){if(l==r)return void(g[l]=F[0]);poly __F(r-l+1);for(int i=0,ed=r-l+1;i<ed;++i)__F[i]=F[i];int mid=l+r>>1;_E_Calc(p<<1,l,mid,_E_Mul(__F,__Q[p<<1|1]),g);_E_Calc(p<<1|1,mid+1,r,_E_Mul(__F,__Q[p<<1]),g);}vector<poly>__P;void _I_Init(int p,int l,int r,const poly&x){if(l==r){__P[p].resize(2),__P[p][0]=(x[l]?mod-x[l]:0),__P[p][1]=1;return;}int mid=l+r>>1;_I_Init(p<<1,l,mid,x),_I_Init(p<<1|1,mid+1,r,x);__P[p]=__P[p<<1]*__P[p<<1|1];}poly _I_Calc(int p,int l,int r,const poly&t){if(l==r)return poly(1,t[l]);int mid=l+r>>1;poly L(_I_Calc(p<<1,l,mid,t)),R(_I_Calc(p<<1|1,mid+1,r,t));L=L*__P[p<<1|1],R=R*__P[p<<1];for(int i=0;i<(int)R.size();++i){L[i]=L[i]+R[i];if(L[i]>=mod)L[i]-=mod;}return L;}}inline poly poly::eval(int n,poly a)const{using namespace __multipoint_operation__;n=max(n,size());poly v(n),F(f);__Q.resize(n<<2);F.resize(n+1),a.resize(n);_E_Init(1,0,n-1,a);__Q[1].resize(n+1);_E_Calc(1,0,n-1,_E_Mul(F,__Q[1].inv()),v);return v;}inline poly poly::intp(int n,const poly&x,const poly&y){using namespace __multipoint_operation__;__P.resize(n<<2);_I_Init(1,0,n-1,x);__P[1]=__P[1].deri();poly t=__P[1].eval(n,x);for(int i=0;i<n;++i)t[i]=1ll*y[i]*qp(t[i],mod-2)%mod;f=_I_Calc(1,0,n-1,t);return*this;}}using math::gfac;using math::gifc;using math::ginv;using math::qp;using math::basic_math::gC;using namespace polynomial;
    namespace plugins{using math::gfac;using math::gifc;using math::ginv;using math::qp;using polynomial::poly;poly _S1R_solve(const int&n){if(n==0)return poly(1,1);int mid=n>>1;poly f=_S1R_solve(mid);f.resize(mid+1);poly A=f.shift(mid),B(mid+1);for(register int i=0;i<=mid;++i)B[i]=f[i];A*=B,f.resize(n+1);if(n&1)for(register int i=0;i<=n;++i)f[i]=((i?A[i-1]:0)+1ll*(n-1)*A[i])%mod;else for(register int i=0;i<=n;++i)f[i]=A[i];return f;}inline poly stirling2_row(const int&n){poly A(n+1),B(n+1);for(register int i=0;i<=n;i++)A[i]=(i&1?mod-gifc(i):gifc(i)),B[i]=1ll*qp(i,n)*gifc(i)%mod;return(A*B).split(n);}inline poly stirling2_col(const int&n,const int&k){poly f(n+1);rep(i,1,n)f[i]=gifc(i);f=f.pow(k);rep(i,0,n)f[i]=1ll*f[i]*gfac(i)%mod*gifc(k)%mod;return f;}inline poly stirling1_row(const int&n){return _S1R_solve(n);}inline poly stirling1_col(const int&n,const int&k){poly f(n+1);f[0]=1,f[1]=mod-1;f=f.inv().ln().pow(k);rep(i,0,n)f[i]=1ll*f[i]*gfac(i)%mod*gifc(k)%mod;return f;}inline poly SEQ(const poly&A){return(1-A).inv();}inline poly Q(const poly&A){return SEQ(A);}inline poly MSET(const poly&A){poly ret(A);for(register int i=2;i<A.size();++i)for(register int j=1;i*j<A.size();++j)ret[i*j]=(ret[i*j]+1ll*ginv(i)*A[j])%mod;return ret.exp();}inline poly Exp(const poly&A){return MSET(A);}inline poly Ln(poly f){f[0]=1;f=f.ln();for(register int i=1;i<f.size();++i)f[i]=1ll*f[i]*i%mod;poly prime(f.size()+1),mu(f.size()+1),ret(f.size());vector<bool>vis(f.size()+1);int cnt=0;mu[1]=1;for(register int i=2;i<=f.size();++i){if(!vis[i])prime[++cnt]=i,mu[i]=mod-1;for(register int j=1;j<=cnt and i*prime[j]<=f.size();++j){vis[i*prime[j]]=1;if(i%prime[j]==0)break;mu[i*prime[j]]=(mu[i]==0?0:mod-mu[i]);}}for(register int i=1;i<f.size();++i)for(register int j=1;i*j<f.size();++j)ret[i*j]=(ret[i*j]+1ll*f[i]*mu[j])%mod;for(register int i=1;i<ret.size();++i)if(ret[i])ret[i]=1ll*ret[i]*ginv(i)%mod;ret[0]=0;return ret;}inline int _R_Div(poly F,poly G,ll n){using namespace polynomial::fast_number_theory_transform;int len=max(F.size(),G.size());int m=1,o=0;while(m<len)m<<=1,++o;F.resize(1<<o+1),G.resize(1<<o+1);while(n>m){ntt(F.data(),o+1),ntt(G.data(),o+1);for(register int i=0;i<m*2;++i)F[i]=1ll*F[i]*G[i^1]%mod;for(register int i=0;i<m;++i)G[i]=1ll*G[i<<1]*G[i<<1|1]%mod;intt(F.data(),o+1);intt(G.data(),o);for(register int i=0,j=n&1;i<len;i++,j+=2)F[i]=F[j];for(register int i=len,ed=1<<o+1;i<ed;++i)F[i]=G[i]=0;n>>=1;}G.resize(m);G=G.inv();int s=n;n=F.size()-1,m=G.size()-1;int a=max(0,s-m),b=min(s,n),ans=0;for(register int i=a;i<=b;++i)ans=(ans+1ll*F[i]*G[s-i])%mod;return ans;}inline int linear_recur(ll n,int k,poly f,poly a){poly F(k+1);F[k]=1;assert(a.size()>=k);a.resize(k);for(register int i=1;i<=k;++i)assert(0<=f[i]and f[i]<mod),F[k-i]=(f[i]==0?0:mod-f[i]);F.rev();f=(a*F).split(a.degree());return _R_Div(f,F,n);}inline poly BM(int n,poly a){a.f.emplace(a.f.begin(),0);poly ans,lst;i32 w=0;ll delt=0;for(register int i=1;i<=n;++i){ll tmp=0;for(register int j=0;j<ans.size();++j)tmp=(tmp+1ll*a[i-j-1]*ans[j])%mod;if((a[i]-tmp+mod)%mod==0)continue;if(!w){w=i,delt=a[i]-tmp+mod;if(delt>=mod)delt-=mod;for(register int j=i;j;--j)ans.f.emplace_back(0);continue;}poly now=ans;ll mult=1ll*(a[i]-tmp+mod)*qp(delt,mod-2)%mod;if(ans.size()<lst.size()+i-w)ans.resize(lst.size()+i-w);ans[i-w-1]+=mult;if(ans[i-w-1]>=mod)ans[i-w-1]-=mod;for(register int j=0;j<lst.size();++j)ans[i-w+j]=(ans[i-w+j]-1ll*mult*lst[j]%mod+mod)%mod;if(now.size()-i<lst.size()-w)lst=now,w=i,delt=(a[i]-tmp+mod)%mod;}return ans;}inline int recur_by_bm(ll n,int k,poly a){poly f=BM(k,a);cout<<f<<'\n';if(f.size()==1)return 1ll*a[0]*qp(f[0],n-1)%mod;f.f.emplace(f.f.begin(),0);return linear_recur(n,f.degree(),f,a);}}using namespace plugins;
} using namespace __POLY__;

const int L = 1 << 21;
int w[2][L];
int iur() {
    int w0 = qp(proot, (mod - 1) / L);
    w[1][0] = w[0][0] = 1;
    for (int i = 1; i < L; ++ i) 
        w[1][i] = w[0][L - i] = 1ll * w[1][i - 1] * w0 % mod;
    return 1;
} bool dummy = iur();

int btrs[L];
int init(int l) {
    l = 1 << lg(l - 1) + 1;
    for (int i = 0; i < l; ++ i) 
        btrs[i] = (btrs[i >> 1] >> 1) | (i & 1 ? l >> 1 : 0);
    return l;
}

void ntt(poly *a, const int& len, const int& typ) {
    for (int i = 0; i < len; ++ i) if (i < btrs[i]) swap(a[i], a[btrs[i]]);
    for (int mid = 1; mid < len; mid <<= 1) 
        for (int i = L / (mid << 1), j = 0; j < len; j += (mid << 1)) 
            for (int k = 0; k < mid; ++ k) {
                poly g = a[j + k + mid] * w[typ][i * k];
                a[j + k + mid] = a[j + k] - g;
                a[j + k] += g;
            }
    if (typ == 1) return;
    int iv = qp(len, mod - 2);
    for (int i = 0; i < len; ++ i) a[i] *= iv;
}

struct Poly { // 正方形的
    vector<poly> f;
    Poly(const int len = 0) { f.resize(len); rep(i,0,len - 1) f[i].resize(len); }
    inline Poly& redegree(int u) {
        f.resize(u + 1);
        rep(i,0,u) f[i].redegree(u);
        return *this;
    }
    inline poly& operator[] (const int& p) { return f[p]; }
    inline const poly operator[] (const int& p) const { return f[p]; }
    inline Poly& resize(int u) { return redegree(u - 1); }
    inline int size() const { return f.size(); }
    inline int degree() const { return size() - 1; }
    inline poly* data() { return f.data(); }
    inline vector<poly>::iterator begin() { return f.begin(); }
    inline vector<poly>::iterator end() { return f.end(); }
    inline const vector<poly>::const_iterator begin() const { return f.begin(); }
    inline const vector<poly>::const_iterator end() const { return f.end(); }
    inline Poly split(int deg) const {
        Poly ret(deg + 1);
        if (deg >= degree()) {
            rep(i,0,degree()) ret[i] = f[i], ret[i].redegree(deg);
        } else {
            rep(i,0,deg) rep(j,0,deg) ret[i][j] = f[i][j];
        } return ret;
    }
    inline friend Poly operator+ (Poly a, const Poly& b) {
        a.redegree(max(a.degree(), b.degree()));
        rep(i,0,b.degree()) a[i] += b[i];
        return a;
    }
    inline friend Poly operator- (Poly a, const Poly& b) {
        a.redegree(max(a.degree(), b.degree()));
        rep(i,0,b.degree()) a[i] -= b[i];
        return a;
    }
    inline friend Poly operator* (Poly a, int b) {
        for (auto& pl : a) pl *= b;
        return a;
    }
    inline friend Poly operator* (int b, Poly a) {
        for (auto& pl : a) pl *= b;
        return a;
    }
    inline friend Poly operator* (Poly a, Poly b) {
        int l = a.size() + b.size() - 1, o = init(l);
        a.resize(o), b.resize(o);
        ntt(a.data(), o, 1); ntt(b.data(), o, 1);
        for (int i = 0; i < o; ++ i) a[i] *= b[i];
        ntt(a.data(), o, 0);
        a.resize(l);
        return a;
    } 

    inline friend istream& operator >> (istream& in, Poly& F) {
        for (auto& pl : F) in >> pl;
        return in;
    }
    inline friend ostream& operator << (ostream& out, const Poly& F) {
        for (int i = 0; i < F.degree(); ++ i) {
            cout << F[i] << '\n';
        } cout << F.f.back(); return out;
    }

    inline Poly inv() const {
        Poly ret(1); ret[0][0] = 1;
        int edp = 1 << lg(size()) + 2;
        for (int k = 2; k <= edp; k <<= 1) {
            ret.redegree(k); 
            Poly p2 = split(k);
            p2.redegree(k); 
            p2 = p2 * ret; p2.redegree(k);
            p2 = p2 * ret; p2.redegree(k);
            ret = ret * 2 - p2;
        } return ret.split(degree());
    }

    inline Poly deri() const {
        Poly ret(size());
        for (int i = 0; i + 1 < size(); ++ i)
            ret[i] = f[i + 1] * (i + 1);
        return ret; 
    }
    inline Poly intg() const {
        Poly ret(size());
        for (int i = degree(); i > 0; -- i) 
            ret[i] = f[i - 1] * ginv(i);
        return ret;
    }
    inline Poly ln() const {
        Poly ret, tmp = 1 - *this, bse = 1 - *this;
        rep(i,1,degree() << 1) {
            ret = ret - tmp * ginv(i);
            tmp = tmp * bse; tmp.redegree(degree());
        } return ret;
    }
    inline Poly exp() const {
        Poly ret, tmp = *this;
        rep(i,1,degree() << 1) {
            ret = ret + tmp * gifc(i);
            tmp = tmp * *this; tmp.redegree(degree());
        } return ret;
    }
/*  
    inline Poly ln() const {
        Poly ret = deri() * inv();
        ret = ret.intg(); 
        return ret.redegree(degree());
    }
    inline Poly exp() const {
        Poly ret(1), A, B; ret[0][0] = 1;
        int edp = 1 << lg(size()) + 2;
        for (int k = 2; k <= edp; k <<= 1) {
            ret.redegree(k); A = ret.ln();
            B = split(k) - A;
            B[0][0] ++;
            ret = ret * B;
        } return ret.redegree(degree());
    }
*/
};

signed main() {
    int n, m;
    cin >> n;
    Poly a(n + 1);
    cin >> a;
    cout << a.deri().intg() << endl;
    timer;
} 
/*

4
0 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9

*/
posted @ 2023-02-12 19:56  joke3579  阅读(115)  评论(3编辑  收藏  举报