QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#137831#4491. Find the Number of PathsWhangZjianAC ✓7527ms182460kbC++143.8kb2023-08-10 18:03:142023-08-10 18:03:16

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-08-10 18:03:16]
  • 评测
  • 测评结果:AC
  • 用时:7527ms
  • 内存:182460kb
  • [2023-08-10 18:03:14]
  • 提交

answer

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e6+21,p=998244353,G=3,RG=332748118;
int r[N],invnum[N];
int ksm(int a,int b){
	int res=1;
	for(;b>0;b>>=1){
		if(b&1) res=res*a%p;
		a=a*a%p;
	}
	return res;
}
struct poly{
	int len,a[N];
	void mems(){
		for(int i=0;i<len;i++) a[i]=0;
	}
	void memc(poly &b){
		mems();
		len=b.len;
		for(int i=0;i<len;i++) a[i]=b.a[i];
	}
	void ntt(int fl){
		for(int i=0;i<len;i++)
			if(i<r[i]) swap(a[i],a[r[i]]);
		for(int sz=1;sz<len;sz<<=1){
			int bu=sz<<1,gn=ksm(fl?G:RG,(p-1)/bu);
			for(int i=0;i<len;i+=bu){
				int g=1;
				for(int j=0;j<sz;j++,g=g*gn%p){
					int x=a[i+j],y=g*a[i+j+sz]%p;
					a[i+j]=(x+y)%p;
					a[i+j+sz]=(x-y+p)%p;
				}
			}
		}
	}
	void digmulti(int v){
		for(int i=0;i<len;i++) a[i]=(a[i]*v%p+p)%p;
	}
	void multi(poly &a,poly &b,poly &res){
		int lim=1,lgn=0,rlim,tlen=a.len+b.len-1;
		for(;lim<tlen;lim<<=1,lgn++);
		for(int i=0;i<lim;i++)
			r[i]=(r[i>>1]>>1)|((i&1)<<(lgn-1));
		a.len=b.len=res.len=lim;
		res.mems();
		a.ntt(1),b.ntt(1);
		for(int i=0;i<lim;i++) res.a[i]=a.a[i]*b.a[i]%p;
		res.ntt(0);
		rlim=ksm(lim,p-2);
		for(int i=0;i<lim;i++) res.a[i]=res.a[i]*rlim%p;
		res.len=tlen;
	}
	void add(poly &a,poly &b,poly &res,int fl){
		res.mems();
		res.len=max(a.len,b.len);
		for(int i=0;i<res.len;i++)
			res.a[i]=(a.a[i]+b.a[i]*fl+p)%p;
	}
	void dao(poly &res){
		res.len=len-1;
		for(int i=0;i<res.len;i++) 
			res.a[i]=a[i+1]*(i+1)%p;
	}
	void ji(poly &res){
		res.len=len+1;
		for(int i=res.len-1;i>0;i--) 
			res.a[i]=a[i-1]*invnum[i]%p;
		res.a[0]=0;
	}
}f,tmp1,tmp2,tmpr,tmpln,I,res;
void ny(poly &f,poly &g2,int n){
	if(n==1){
		g2.len=1;
		g2.a[0]=ksm(f.a[0],p-2);
		return;
	}
	int rn=f.len;
	ny(f,g2,(n+1)>>1);
	tmp1.memc(g2),tmp2.memc(g2); 
	g2.multi(tmp1,tmp2,tmpr);
	tmp1.memc(tmpr);
	/*tmp2.mems();
	tmp2.len=n;
	for(int i=0;i<n;i++) tmp2.a[i]=f.a[i];*/
	f.len=n;tmp2.memc(f);f.len=rn;
	g2.multi(tmp1,tmp2,tmpr);
	g2.digmulti(2);
	tmp1.memc(g2);
	g2.add(tmp1,tmpr,g2,-1);
	g2.len=n;
}
void ln(poly &f,poly &res){
	poly fd,g2;
	f.dao(fd);
	ny(f,g2,f.len);
	tmp1.memc(g2),tmp2.memc(fd);
	tmpr.multi(tmp1,tmp2,tmpr);
	tmpr.ji(res);
}
void exp(poly &g,poly &f,int n){
	if(n==1){
		g.len=1;
		g.a[0]=1;
		return;
	}
	exp(g,f,(n+1)>>1);
	int rn=f.len;
	g.len=n;
	ln(g,tmpln);
	tmpln.len=n;
	f.len=n;
	tmpr.add(I,tmpln,tmpr,-1);
	tmp1.memc(tmpr);
	tmpr.add(tmp1,f,tmpr,1);
	f.len=rn;
	tmp1.memc(g),tmp2.memc(tmpr);
	g.multi(tmp1,tmp2,g);
	g.len=n;
}
poly A,B,C,invB,tmpB;
int n,k;

signed main(){
	int T;
	I.len=1,I.a[0]=1; 
	cin>>T;
	for(int i=0;i<=2e6;i++) invnum[i]=ksm(i,p-2);
	while(T--){
		cin>>n>>k;
		A.mems(),B.mems(),C.mems(),invB.mems(),tmpB.mems(),f.mems(),res.mems();
		tmp1.mems(),tmp2.mems(),tmpln.mems(),tmpr.mems();
		for(int i=1;i<n;i++)
			scanf("%lld",&A.a[i]);
		A.len=n+k;
		f.len=n+k;
		f.a[n-1]=1;
		A.ji(B);
		B.digmulti(-1);
		B.len=n+k;
		exp(tmpB,B,B.len);
		B.memc(tmpB);
		tmpB.memc(B);
		ny(tmpB,invB,B.len);
		tmp1.memc(f),tmp2.memc(invB);
		C.multi(tmp1,tmp2,C);
		C.len=n+k;
		int tmp=1;
		for(int i=1;i<=k;i++) tmp=tmp*i%p;
		for(int i=0;i<n;i++){
			C.a[i]=C.a[i+k]*tmp%p;
			tmp=tmp*invnum[i+1]%p*(i+k+1)%p;
		} 
	//	for(int i=1;i<=k;i++){
		/*	tmp1.memc(f),tmp2.memc(invB);
			C.multi(tmp1,tmp2,C);
			f.len=n+k,C.len=n+k;
			C.dao(tmp1);tmp2.memc(B);
			f.multi(tmp1,tmp2,f);*/
			
		/*	f.dao(tmpf),tmp1.memc(A),tmp2.memc(f);
			tmpr.multi(tmp1,tmp2,tmpr);
			f.add(tmpf,tmpr,f,1);*/
	//	}
		B.len=C.len=n;
		tmp1.memc(C),tmp2.memc(B);
		res.multi(tmp1,tmp2,res);
		for(int i=n-1;i>=0;i--){
			printf("%lld ",res.a[i]);
		}
		printf("\n");
	}
}
/*
4
3 2
1 2
3 1
1 2
5 10
2 3 3 3
3 3
166374059 748683265

4
0 0 499122177 665496236
*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 7527ms
memory: 182460kb

input:

14
3 2
1 2

3 1
1 2

7 10
1 1 4 5 1 4

2 1
998244352

18 32
1 0 1 0 1 0 0 0 0 1 1 1 0 0 0 0 1

188 19
633886818 153877981 415015507 40745200 269787796 274990221 297547338 934403707 463583160 490465672 641355195 897012511 641637182 821068661 614724038 55504516 717220803 796828809 578138752 516258420 ...

output:

5 0 2 
0 2 0 
475251424 113315999 791330691 478266847 175921200 46569600 4082400 
0 1 
290297689 111948457 905336170 325091865 481715174 560516169 711953201 909617930 834449213 230629315 299970170 870572449 496138561 512305244 580683156 556935218 282162750 458443581 
900977301 704879246 103685386 11...

result:

ok 14 lines