56pts 1~14 BM 板子求调 qwq
查看原帖
56pts 1~14 BM 板子求调 qwq
109114
_l_l_¯l¯l¯楼主2024/1/11 17:59

常系数齐次已经过了

#pragma GCC optimize("Ofast")
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int mod = 998244353;
inline int qkpow(int a,int b){int ans=1;for(;b;b>>=1,a=(long long)a*a%mod){if(b&1)ans=(long long)ans*a%mod;}return ans;}
void eRRoR(const char*str){puts(str);int p=str[0];p-=str[0];p=p/p;printf("%d",p);}template<const int MAXL,const int mod>class NTT{inline static int add(int x,const int&y){x+=y;if(x>=mod)x-=mod;return x;}inline int sub(int x,const int&y){x-=y;if(x<0)x+=mod;return x;}inline int qkpow(int a,int b){int ans=1;for(;b;b>>=1,a=(long long)a*a%mod){if(b&1)ans=(long long)ans*a%mod;}return ans;}const int g=3,invg=qkpow(g,mod-2);int rev[MAXL],wpre[2][MAXL<<1];int F[MAXL],G[MAXL],H[MAXL];struct complex{long long r,i,ii;complex(const long long Ii,const long long R=0,const long long I=0){r=R;i=I;ii=Ii;}complex operator*(complex sec){return complex(ii,add(r*sec.r%mod,ii*i%mod*sec.i%mod),add(r*sec.i%mod,i*sec.r%mod));}};inline complex qkpow(complex a,int b){complex ans=complex(a.ii,1,0);for(;b;b>>=1,a=a*a){if(b&1)ans=ans*a;}return ans;}inline long long Cipolla(const long long a){if(a==0)return 0;if(a==1)return 1;if(qkpow(a,mod>>1)==mod-1)return 1/(a-a);long long b,ii;do{b=rand()%mod;ii=((b*b-a)%mod+mod)%mod;}while(qkpow(ii,mod>>1)!=mod-1);complex c=qkpow(complex(ii,b,1),(mod+1)>>1);return min(c.r,mod-c.r);}public:NTT(){int w0p=mod-1;for(int i=1;i<MAXL;i<<=1){int w0pl=qkpow(g,w0p>>=1);int w0ng=qkpow(invg,w0p);wpre[0][i]=wpre[1][i]=1;for(int j=1;j<i;j++)wpre[0][i+j]=(long long)wpre[0][i+j-1]*w0pl%mod;for(int j=1;j<i;j++)wpre[1][i+j]=(long long)wpre[1][i+j-1]*w0ng%mod;}}inline int prev_(const int*a,const int&n,const int&LL){int L=1,lL=0;while(L<=LL)L<<=1,lL++;for(int i=0;i<L;i++)rev[i]=rev[i>>1]>>1|(i&1)<<(lL-1);memmove(F,a,(n+1)<<2);memset(F+n+1,0,(L-n-1)<<2);return L;}inline int prev_(const int*a,const int*b,const int n,const int m,const int LL){const int L=prev_(a,n,LL);memmove(G,b,(m+1)<<2);memset(G+m+1,0,(L-m-1)<<2);return L;}inline int prev_(const int*a,const int*b,const int*c,const int n,const int m,const int k,const int LL){const int L=prev_(a,b,n,m,LL);memmove(H,c,(k+1)<<2);memset(H+k+1,0,(L-k-1)<<2);return L;}inline void DFT(int*a,const int L,const bool op){for(int i=0;i<L;i++)if(i<rev[i])swap(a[i],a[rev[i]]);for(int len=1;len<L;len<<=1){for(int l=0;l<L;l+=len<<1){for(int it=l;it<l+len;it++){int x=a[it],y=(long long)a[it+len]*wpre[op][len+it-l]%mod;a[it]=add(x,y);a[it+len]=sub(x,y);}}}if(op){int invL=qkpow(L,mod-2);for(int i=0;i<L;i++)a[i]=(long long)a[i]*invL%mod;}}inline void mul(const int*a,const int*b,const int n,const int m,int*ans){int L=prev_(a,b,n,m,n+m);DFT(F,L,0);DFT(G,L,0);for(int i=0;i<L;i++)F[i]=(long long)F[i]*G[i]%mod;DFT(F,L,1);memcpy(ans,F,(n+m+1)<<2);}inline void inv(const int n,const int*a,int*b){if(n==0){if(a[0]==0)eRRoR("NTT::inv()");b[0]=qkpow(a[0],mod-2);return;}inv(n>>1,a,b);int L=prev_(a,b,n,n>>1,n+(n>>1<<1));DFT(F,L,0);DFT(G,L,0);for(int i=0;i<L;i++)F[i]=(2ll*G[i]+(long long)mod*mod-(long long)F[i]*G[i]%mod*G[i])%mod;DFT(F,L,1);memcpy(b,F,(n+1)<<2);}inline void sqrt(const int n,const int*a,int*b){if(n==0){b[0]=Cipolla(a[0]);if(b[0]==-1)eRRoR("NTT::sqrt()");return;}sqrt(n>>1,a,b);for(int i=(n>>1)+1;i<=n;i++)b[i]=0;memset(b+(n>>1)+1,0,(n-(n>>1))<<2);static int invb[MAXL];inv(n,b,invb);int L=prev_(a,b,invb,n,n>>1,n,n+n);DFT(F,L,0);DFT(G,L,0);DFT(H,L,0);int inv2=qkpow(2,mod-2);for(int i=0;i<L;i++)F[i]=((long long)F[i]*H[i]+G[i])%mod*inv2%mod;DFT(F,L,1);memcpy(b,F,(n+1)<<2);}inline void differentiate(const int n,const int*a,int*b){for(int i=0;i<n;i++)b[i]=(long long)a[i+1]*(i+1)%mod;b[n]=0;}inline void integral(const int n,const int*a,int*b){for(int i=1;i<=n+1;i++)b[i]=(long long)a[i-1]*qkpow(i,mod-2)%mod;b[0]=0;}inline void ln(const int n,const int*a,int*b){if(a[0]!=1)eRRoR("NTT::ln()");static int tmp[MAXL],tmp2[MAXL];differentiate(n,a,tmp);inv(n,a,tmp2);int L=prev_(tmp,tmp2,n,n,n+n);DFT(F,L,0);DFT(G,L,0);for(int i=0;i<L;i++)F[i]=(long long)F[i]*G[i]%mod;DFT(F,L,1);integral(n-1,F,b);}inline void exp(const int n,const int*a,int*b){if(n==0){if(a[0]!=0)eRRoR("NTT::exp()");b[0]=1;return;}exp(n>>1,a,b);memset(b+(n>>1)+1,0,(n-(n>>1))<<2);static int lnb[MAXL];ln(n,b,lnb);int L=prev_(a,b,lnb,n,n>>1,n,n+n);DFT(F,L,0);DFT(G,L,0);DFT(H,L,0);for(int i=0;i<L;i++)F[i]=(1ll-H[i]+F[i]+mod)*G[i]%mod;DFT(F,L,1);memcpy(b,F,(n+1)<<2);}inline void pow(const int n,const int*a,const int km,int*b,int km1=-1,const bool flg=0){if(km1==-1)km1=km;static int tmp[MAXL],tmp2[MAXL];int ls=0;while(a[ls]==0&&ls<=n)ls++;if(ls==n+1||(ls>0&&(flg||(long long)ls*km>n))){for(int i=0;i<=n;i++)b[i]=0;if(ls==n+1&&flg==0&&km==0)b[0]=1;return;}const int inva=qkpow(a[ls],mod-2);for(int i=0;i<=n;i++)tmp2[i]=(long long)a[i]*inva%mod;ln(n-ls,tmp2+ls,tmp);for(int i=0;i<=n-ls;i++)tmp[i]=(long long)tmp[i]*km%mod;exp(n-ls,tmp,b);const int bak=qkpow(a[ls],km1);for(int i=n;i>=ls*km;i--)b[i]=(long long)b[i-ls*km]*bak%mod;for(int i=ls*km-1;~i;i--)b[i]=0;}inline void div(const int n,const int m,const int*a,const int*b,int*q,int*r){if(n<m){memcpy(r,a,(n+1)<<2);return;}static int tmp1[MAXL],tmp2[MAXL],tmp3[MAXL];for(int i=0;i<=m;i++)tmp2[i]=b[m-i];if(n>m)memset(tmp2+m+1,0,(n-m)<<2);inv(n,tmp2,tmp3);for(int i=0;i<=n;i++)tmp2[i]=a[n-i];int L=prev_(tmp2,tmp3,n,n,n<<1);DFT(F,L,0);DFT(G,L,0);for(int i=0;i<L;i++)tmp2[i]=(long long)F[i]*G[i]%mod;DFT(tmp2,L,1);if(q!=NULL)for(int i=0;i<=n-m;i++)q[n-m-i]=tmp1[n-m-i]=tmp2[i];else for(int i=0;i<=n-m;i++)tmp1[n-m-i]=tmp2[i];if(r==NULL)return;memcpy(tmp2,tmp1,(n-m+1)<<2);memcpy(tmp1,a,(n+1)<<2);memcpy(tmp3,b,(m+1)<<2);L=prev_(tmp1,tmp2,tmp3,n,n-m,m,n<<1);DFT(F,L,0);DFT(G,L,0);DFT(H,L,0);for(int i=0;i<L;i++)F[i]=(F[i]+(long long)mod*mod-(long long)G[i]*H[i])%mod;DFT(F,L,1);memcpy(r,F,m<<2);}inline void PolynomialChallenge(const int n,const int k,const int*a,int*b){static int F[MAXL],G[MAXL];sqrt(n,a,F);inv(n,F,G);integral(n,G,F);exp(n+1,F,G);for(int i=0;i<=n;i++)G[i]=(a[i]+mod-G[i])%mod;G[n+1]=(mod-G[n+1])%mod;G[0]-=a[0];G[0]+=2;ln(n+1,G,F);F[0]++;pow(n+1,F,k,G,k%(mod-1),k==mod-1);differentiate(n+1,G,F);memcpy(b,F,(n+1)<<2);}};template<int MAXL,int mod>struct Polynomial{inline int qkpow(int a,int b)const{int res=1;for(;b;b>>=1,a=(long long)a*a%mod){if(b&1)res=(long long)res*a%mod;}return res;}NTT<MAXL,mod>*ntt;public:int len,*f;inline Polynomial(){f=new int[MAXL+10];len=-1;ntt=NULL;}inline Polynomial(NTT<MAXL,mod>*ntt_,int len_=-1){f=new int[MAXL+10];len=len_;memset(f,0,(len+1)<<2);ntt=ntt_;}template<typename Tp>inline Polynomial(NTT<MAXL,mod>*ntt_,int len_,Tp generator){f=new int[MAXL+10];len=len_;for(int i=0;i<=len;i++)f[i]=generator(i);ntt=ntt_;}inline Polynomial(NTT<MAXL,mod>*ntt_,const int*ptl,const int*ptr){f=new int[MAXL+10];len=ptr-ptl-1;memcpy(f,ptl,(ptr-ptl)<<2);ntt=ntt_;}inline Polynomial(const Polynomial&sec){f=new int[MAXL+10];len=sec.len;memcpy(f,sec.f,(len+1)<<2);ntt=sec.ntt;}inline Polynomial&operator=(const Polynomial&sec){len=sec.len;memcpy(f,sec.f,(len+1)<<2);ntt=sec.ntt;return*this;}inline~Polynomial(){delete[]f;}inline Polynomial&resize(int _len){if(len<_len)memset(f+len+1,0,(_len-len)<<2);len=_len;return*this;}inline Polynomial operator+(const int&x)const{Polynomial res(*this);res.f[0]+=x;if(res.f[0]>=mod)res.f[0]-=mod;return res;}inline friend Polynomial operator+(const int&x,const Polynomial&p){return p+x;}inline Polynomial&operator+=(const int&x){f[0]+=x;if(f[0]>=mod)f[0]-=mod;return*this;}inline Polynomial operator+(const Polynomial&p)const{Polynomial res(ntt,max(len,p.len));for(int i=0;i<=len;i++)res.f[i]=f[i];for(int i=0;i<=p.len;i++){res.f[i]+=p.f[i];if(res.f[i]>=mod)res.f[i]-=mod;}return res;}inline Polynomial&operator+=(const Polynomial&p)const{len=max(len,p.len);for(int i=0;i<=p.len;i++){f[i]+=p.f[i];if(f[i]>=mod)f[i]-=mod;}return*this;}inline Polynomial operator-(const int&x)const{Polynomial res(*this);res.f[0]-=x;if(res.f[0]<0)res.f[0]+=mod;return res;}inline Polynomial operator-()const{Polynomial res(*this);for(int i=0;i<=res.len;i++){res.f[i]=mod-res.f[i];if(res.f[i]==mod)res.f[i]=0;}return res;}inline friend Polynomial operator-(const int&x,const Polynomial&p){return x+-p;}inline Polynomial&operator-=(const int&x){f[0]-=x;if(f[0]<0)f[0]+=mod;return*this;}inline Polynomial operator-(const Polynomial&p)const{Polynomial res(ntt,max(len,p.len));for(int i=0;i<=len;i++)res.f[i]=f[i];for(int i=0;i<=p.len;i++){res.f[i]-=p.f[i];if(res.f[i]<0)res.f[i]+=mod;}return res;}inline Polynomial&operator-=(const Polynomial&p)const{len=max(len,p.len);for(int i=0;i<=p.len;i++){f[i]-=p.f[i];if(f[i]<0)f[i]+=mod;}return*this;}inline Polynomial operator*(const int&x)const{Polynomial res(ntt,len);for(int i=0;i<=len;i++)res.f[i]=(long long)f[i]*x%mod;return res;}inline friend Polynomial operator*(const int&x,const Polynomial&p){return p*x;}inline Polynomial&operator*=(const int&x){for(int i=0;i<=len;i++)f[i]=(long long)f[i]*x%mod;return*this;}inline Polynomial operator*(const Polynomial&p)const{Polynomial res(ntt,len+p.len);ntt->mul(f,p.f,len,p.len,res.f);return res;}inline Polynomial&operator*=(const Polynomial&p){ntt->mul(f,p.f,len,p.len,f);len+=p.len;return*this;}inline Polynomial operator/(const int&x)const{return this->operator*(qkpow(x,mod-2));}inline friend Polynomial operator/(const int&x,const Polynomial&p){return x*p.inv();}inline Polynomial&operator/=(const int&x){return(*this*=qkpow(x,mod-2));}inline Polynomial operator/(const Polynomial&p)const{Polynomial res(ntt,len-p.len);ntt->div(len,p.len,f,p.f,res.f,NULL);return res;}inline Polynomial&operator/=(const Polynomial&p){ntt->div(len,p.len,f,p.f,f,NULL);len-=p.len;return*this;}inline Polynomial operator%(const Polynomial&p)const{Polynomial res(ntt,p.len-1);ntt->div(len,p.len,f,p.f,NULL,res.f);return res;}inline Polynomial&operator%=(const Polynomial&p){ntt->div(len,p.len,f,p.f,NULL,f);len=p.len-1;return*this;}inline Polynomial inv()const{Polynomial res(ntt,len);ntt->inv(len,f,res.f);return res;}inline Polynomial sqrt()const{Polynomial res(ntt,len);ntt->sqrt(len,f,res.f);return res;}inline Polynomial differentiate()const{Polynomial res(ntt,len);ntt->differentiate(len,f,res.f);return res;}inline Polynomial integral()const{Polynomial res(ntt,len+1);ntt->integral(len,f,res.f);return res;}inline Polynomial ln()const{Polynomial res(ntt,len);ntt->ln(len,f,res.f);return res;}inline Polynomial exp()const{Polynomial res(ntt,len);ntt->exp(len,f,res.f);return res;}inline Polynomial operator^(int km){if(km>=mod)km=1/(km-km);Polynomial res(ntt,len);ntt->pow(len,f,km,res.f,km==mod-1?0:km,km==mod-1);return res;}inline Polynomial&operator^=(int km){if(km>=mod)km=1/(km-km);ntt->pow(len,f,km,f,km==mod-1?0:km,km==mod-1);return*this;}inline Polynomial pow(int km,int km1=-1,bool flg=0){if(km>=mod)km=1/(km-km);if(km1>=mod-1)km1=1/(km1-km1);Polynomial res(ntt,len);ntt->pow(len,f,km,res.f,km1,flg);return res;}inline void print(){printf("%d\n",len);for(int i=0;i<=len;i++)printf("%d%c",f[i]," \n"[i==len]);}inline Polynomial compinv()const{if(f[0])eRRoR("Polynomial::compinv()");if(f[1]==0)eRRoR("Polynomial::compinv()");int L=ceil(std::sqrt(len)),L2=ceil((double)len/L);Polynomial*p1=new Polynomial<MAXL,mod>[L2];for(int i=0;i<L2;i++)p1[i].ntt=ntt;Polynomial*p2=new Polynomial<MAXL,mod>[L+1];for(int i=0;i<=L;i++)p2[i].ntt=ntt;p1[0].resize(len-1);p2[0].resize(len);p1[0].f[0]=1;p2[1]=Polynomial(ntt,this->f+1,this->f+len+1).inv();for(int i=2;i<=L;i++)p2[i]=p2[i-1]*p2[1],p2[i].resize(len-1);for(int i=1;i<L2;i++)p1[i]=p1[i-1]*p2[L],p1[i].resize(len-1);for(int i=1;i<=len;i++){int r=(i-1)%L+1,c=(i-r)/L;__int128 tmp=0;for(int j=0;j<len;j++){if(j<=i-1)if(i-1-j<=len-1)tmp+=1ll*p1[c].f[j]*p2[r].f[i-1-j];}p2[0].f[i]=tmp%mod*qkpow(i,mod-2)%mod;}Polynomial ans=p2[0];delete[]p1;delete[]p2;return ans;}void minimize(){while(len>=0&&f[len]==0)len--;}};
#define poly Polynomial
const int MAXL = 1 << 14;
//const int mod = 998244353;
NTT<MAXL, mod> ntt;
int c[MAXL], f[MAXL];
int p[10005], pr[10005], prlen, prdlt, pre, tmppr[10005], tmplen, tmpdlt, nowpr[10005], nowlen;
int main() {
//	freopen("BM-in.txt", "r", stdin);
	int n, m;
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; i++) scanf("%d", &p[i]);
	nowlen = prlen = 0; prdlt = 0; pre = -1; for (int i = 1; i <= n; i++) {
		int dlt = p[i]; for (int j = 1; j <= nowlen; j++) dlt = (dlt + mod - 1ll * p[i - j] * nowpr[j] % mod) % mod;
		if (dlt == 0) continue;
		if (prdlt) {
			tmplen = nowlen; memcpy(tmppr + 1, nowpr + 1, tmplen << 2);
			int x = 1ll * dlt * qkpow(prdlt, mod - 2) % mod; for (int j = 1; j <= prlen; j++) nowpr[i - pre + j - 1] = (nowpr[i - pre + j - 1] + 1ll * x * pr[j]) % mod;
			nowlen = max(nowlen, i - pre + prlen - 1);
//			printf("? %d %d %d %d\n", prlen, x, dlt, qkpow(prdlt, mod - 2));
			prdlt = (mod - dlt) % mod, prlen = tmplen + 1; memcpy(pr + 2, tmppr + 1, tmplen << 2), pr[1] = mod - 1, pre = i;
		}
		else {
			prdlt = dlt; nowlen = prlen = i; pr[1] = 1; pre = i;
		}
//		printf("%d: %d %d:", i, nowlen, dlt); for (int i = 1; i <= nowlen; i++) printf(" %d", nowpr[i]); puts("");
//		printf("%d:", prdlt); for (int i = 1; i <= prlen; i++) printf(" %d", pr[i]); puts("");
	}
	memcpy(f, p, sizeof f);
//	printf("len = %d\n", nowlen);
	for (int i = 1; i <= nowlen; i++) printf("%d ", nowpr[i]); puts("");
//	for (int i = 1; i <= k; i++) scanf("%d", &c[i]), c[i] = (c[i] % mod + mod) % mod;
	poly<MAXL, mod> res(&ntt, 0, [](int id)->int {return 1;}), a(&ntt, 1, [](int id)->int {return id;}), p(&ntt, nowlen);
	for (int i = 0; i < nowlen; i++) p.f[i] = mod - nowpr[nowlen - i]; p.f[nowlen] = 1;
//	printf("m = %d\n", m);
//	for (int i = 0; i <= nowlen; i++) printf("%d\n", p.f[i]);
	for (; m; m >>= 1, a = a * a, a.minimize(), a %= p) {
		if (m & 1) res = res * a, res.minimize(), res %= p;
//		puts("------");
//		for (int i = 0; i < nowlen; i++) printf("%d%c", res.f[i], " \n"[i == nowlen - 1]);
//		for (int i = 0; i < nowlen; i++) printf("%d%c", a.f[i], " \n"[i == nowlen - 1]);
	}
	int ans = 0;
//	for (int i = 0; i < nowlen; i++) printf("%d %d\n", res.f[i], f[i + 1]);
	for (int i = 0; i < nowlen; i++) ans = (ans + 1ll * res.f[i] * f[i + 1]) % mod;
	printf("%d\n", ans);
}
/*
4 10
1 1 2 3
5 10
3 7 27 95 339
*/
2024/1/11 17:59
加载中...