1 条题解
-
0
#include<bits/stdc++.h> #define ll long long using namespace std; #define I ll #define her1 20081214 #define IV void #define cht 998244353 #define ld long double #define Aestas16 392699 #define ull unsigned long long #define cp(x,y)memcpy(x,y,sizeof y) #define mem(x,val)memset(x,val,sizeof x) #define D(i,j,n)for(register int i=j;i>=n;i--) #define E(i,now)for(register int i=first[now];i;i=e[i].nxt) #define F(i,j,n)for(register int i=j;i<=n;i++) #define DL(i,j,n)for(register i64 i=j;i>=n;i--) #define EL(i,now)for(register i64 i=first[now];i;i=e[i].nxt) #define FL(i,j,n)for(register i64 i=j;i<=n;i++) ll read(){ ll ans=0,f=1; char c=getchar(); while(c<'0'||c>'9'){ if(c=='-')f=-1; c=getchar(); } while(c>='0'&&c<='9')ans=ans*10+c-'0',c=getchar(); return ans*f; } #undef ll #include "assert.h" mt19937_64 rnd(her1); #include "functional" using i64 = long long; const int MAX = (1<<19); const int maxn = (1<<19)+5; const int maxm = (1<<19)+5; #define in(i,V) F(i,0,(i64)V.size()-1) #define My_assert(expr,tips) ((expr)?(void(0)):(puts(tips),exit(0))) IV cadd(i64&x,i64 val){x=(x+val)%cht;} i64 w[maxm]; i64 qpow(i64 n,i64 base=cht-2){ i64 ans=1; while(base){ if(base&1)ans=ans*n%cht; n=n*n%cht;base>>=1; } return ans; } IV init(i64 limit){ for(int i=1,j,k;i<limit;i<<=1) for(w[j=i]=1,k=qpow(3,(cht-1)/(i<<1)),j++;j<(i<<1);j++) w[j]=w[j-1]*k%cht; } IV DIT(i64*a,i64 limit){ for(i64 i,j,k=limit>>1,L,*W,*x,*y,z;k;k>>=1) for(L=k<<1,i=0;i<limit;i+=L)for(j=0,W=w+k,x=a+i,y=x+k;j<k;j++,W++,x++,y++) *y=(*x+cht-(z=*y))* *W%cht,*x=(*x+z)%cht; } IV DIF(i64*a,i64 limit){ for(i64 i,j,k=1,L,*W,*x,*y,z;k<limit;k<<=1) for(L=k<<1,i=0;i<limit;i+=L)for(j=0,W=w+k,x=a+i,y=x+k;j<k;j++,W++,x++,y++) z=1ll* *W* *y%cht,*y=(*x-z)%cht,*x=(*x+z)%cht; reverse(a+1,a+limit); i64 inv=qpow(limit); F(i,0,limit-1)a[i]=a[i]*inv%cht; } #define poly vector<i64> IV adjust(poly&C){ while(C.size()&&!C.back()) C.pop_back(); } poly operator*(const poly&A,const poly&B){ if(A.empty()||B.empty())return{}; if(A.size()<=5||B.size()<=5){ poly C(A.size()+B.size()-1); in(i,A)in(j,B)cadd(C[i+j],A[i]*B[j]); adjust(C);return C; } static i64 f[maxm],g[maxm]; My_assert(A.size()&&B.size(),"multiply with a empty poly."); i64 limit=1; while(limit<=A.size()+B.size()) limit<<=1; F(i,0,limit-1)f[i]=g[i]=0; in(i,A)f[i]=A[i];in(i,B)g[i]=B[i]; DIT(f,limit);DIT(g,limit); F(i,0,limit-1)f[i]=f[i]*g[i]%cht;DIF(f,limit); poly C;C.resize(A.size()+B.size()-1); in(i,C)C[i]=f[i];adjust(C);return C; } poly operator+(const poly&A,const poly&B){ poly C;C.resize(max(A.size(),B.size())); in(i,C)C[i]=0; in(i,A)cadd(C[i],A[i]); in(i,B)cadd(C[i],B[i]); return C; } poly operator-(const poly&A,const poly&B){ poly C;C.resize(max(A.size(),B.size())); in(i,C)C[i]=0; in(i,A)cadd(C[i],A[i]); in(i,B)cadd(C[i],-B[i]); return C; } i64 fac[maxn],ifac[maxn]; IV init(){ fac[0]=1;F(i,1,MAX)fac[i]=fac[i-1]*i%cht; ifac[MAX]=qpow(fac[MAX]);D(i,MAX-1,0)ifac[i]=ifac[i+1]*(i+1)%cht; } IV remod(poly&A,i64 n){while(A.size()>n)A.pop_back();} IV print(poly v){ for(auto x:v)cout<<x<<' '; puts(""); } poly binom_poly(i64 nw){ poly Tmp(nw+1); F(i,0,nw)Tmp[i]=((i&1)?-1:1)*fac[nw]*ifac[i]%cht*ifac[nw-i]%cht; return Tmp; } struct frac{ poly p;i64 k; IV adjust(i64 nw){ assert(k<=nw);if(k==nw)return;nw-=k; p=p*binom_poly(nw);k+=nw; } }; frac operator*(const frac&A,const frac&B){return{A.p*B.p,A.k+B.k};} frac operator+(frac A,frac B){ i64 nw=max(A.k,B.k); A.adjust(nw);B.adjust(nw); return{A.p+B.p,nw}; } frac operator-(frac A,frac B){ i64 nw=max(A.k,B.k); A.adjust(nw);B.adjust(nw); return{A.p-B.p,nw}; } struct nfrac{poly p,q;}; nfrac operator*(const nfrac&A,const nfrac&B){return{A.p*B.p,A.q*B.q};} nfrac operator/(const nfrac&A,const nfrac&B){return{A.p*B.q,A.q*B.p};} nfrac operator+(const nfrac&A,const nfrac&B){ return{A.p*B.q+A.q*B.p,A.q*B.q}; } nfrac operator-(const nfrac&A,const nfrac&B){ return{A.p*B.q-A.q*B.p,A.q*B.q}; } nfrac Make(frac x){ return{x.p,binom_poly(x.k)}; } i64 n,m,A[maxn],B[maxn],C[maxn],D[maxn]; frac make(poly A){adjust(A);return{A,0};} struct node{frac A,B,C,D;}t1,t2; node operator+(const node&X,const node&Y){ return{X.A+Y.A,X.B+Y.B,X.C+Y.C,X.D+Y.D}; } node operator*(const node&X,const frac&k){ return{X.A*k,X.B*k,X.C*k,X.D*k}; } pair<node,node>cdq(i64 l,i64 r){ if(l==r){ t1.A.k=t1.B.k=t1.C.k=t1.D.k=0; t1.A=make(poly{0,B[l]}); t1.B=make(poly{0,C[l]}); t1.C=make(poly{0,D[l]}); t1.D=make(poly{l==n}); if(A[l]){ t1.A.k++; t1.B.k++; t1.C.k++; t1.D.k++; } t2.A=make(poly{1}); t2.B=t2.C=t2.D=make(poly{}); return{t1,t2}; } i64 mid=l+r>>1; auto[vl,vlis]=cdq(l,mid); auto[vM,vMis]=cdq(mid+1,r); auto gen=[&](node v)->node{ node nw=vM*v.A+vMis*v.B; nw.C=nw.C+v.C;nw.D=nw.D+v.D; return nw; }; return make_pair(gen(vl),gen(vlis)); } i64 Bostan_Mori(poly f,poly g,i64 n){ while(n){ poly ig=g;in(i,g)if(i&1)ig[i]=-ig[i]; f=f*ig;g=g*ig; poly nf,ng; in(i,f)if((i&1)==(n&1))nf.push_back(f[i]); in(i,g)if(i%2==0)ng.push_back(g[i]); n>>=1; f=nf;g=ng; } if(f.empty())return 0; return f[0]*qpow(g[0])%cht; } int main(){ init();init(1<<19); n=read();m=read(); F(i,1,n)A[i]=read(); F(i,1,n)B[i]=read(); F(i,1,n)C[i]=read(); F(i,1,n)D[i]=read(); D[1]=0; node Tmp=cdq(1,n).first; nfrac Ans=Make(Tmp.D)/Make((make(poly{1})-Tmp.C)); cout<<(Bostan_Mori(Ans.p,Ans.q,m)+cht)%cht; return 0; }
- 1
信息
- ID
- 8858
- 时间
- 8000ms
- 内存
- 1024MiB
- 难度
- 7
- 标签
- 递交数
- 27
- 已通过
- 9
- 上传者