QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#360600#8329. ExcuseyyyyxhTL 5ms8776kbC++145.9kb2024-03-21 22:23:552024-03-21 22:23:56

Judging History

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

  • [2024-03-21 22:23:56]
  • 评测
  • 测评结果:TL
  • 用时:5ms
  • 内存:8776kb
  • [2024-03-21 22:23:55]
  • 提交

answer

#include <cstdio>
#include <vector>
#include <cassert>
#include <algorithm>
#define lc (p<<1)
#define rc (p<<1|1)
#define ALL(p) p.begin(),p.end()
#define IL inline
// #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<22,stdin)),p1==p2?EOF:*p1++)
using namespace std;
char buf[1<<22],*p1=buf,*p2=buf;
int read(){
	char c=getchar();int x=0;bool f=0;
	while(c<48||c>57) f|=(c=='-'),c=getchar();
	do x=x*10+(c^48),c=getchar();
	while(c>=48&&c<=57);
	if(f) return -x;
	return x;
}
typedef vector<int> vi;
const int P=998244353;
typedef long long ll;
IL int qp(int a,int b=P-2){
	int res=1;
	while(b){
		if(b&1) res=(ll)res*a%P;
		a=(ll)a*a%P;b>>=1;
	}
	return res;
}
int len,ilen,bt;
int rev[1<<20],cw[1<<20|1];
IL void init(int _len){ // mod x^len
	len=1;bt=-1;
	while(len<_len) len<<=1,++bt;
	int w=qp(3,(P-1)>>(bt+1));
	cw[0]=cw[len]=1;
	for(int i=1;i<len;++i){
		cw[i]=(ll)cw[i-1]*w%P;
		rev[i]=(rev[i>>1]>>1)|((i&1)<<bt);
	}
	ilen=qp(len);
}
struct poly{
	vi f;
	poly():f(){}
	poly(int Len):f(Len){}
	poly(initializer_list<int> Init):f(Init){}
	IL int& operator[](const int &x){return f[x];}
	IL const int& operator[](const int &x)const{return f[x];}
	IL void NTT(){
		f.resize(len,0);
		for(int i=1;i<len;++i) if(rev[i]<i) swap(f[rev[i]],f[i]);
		for(int i=1,tt=len>>1;i<len;i<<=1,tt>>=1)
			for(int j=0;j<len;j+=(i<<1))
				for(int k=j,t=0;k<(j|i);++k,t+=tt){
					int x=f[k],y=(ll)f[k|i]*cw[t]%P;
					if((f[k]=x+y)>=P) f[k]-=P;
					if((f[k|i]=x-y)<0) f[k|i]+=P;
				}
	}
	IL void INTT(){
		for(int i=1;i<len;++i) if(rev[i]<i) swap(f[rev[i]],f[i]);
		for(int i=1,tt=len>>1;i<len;i<<=1,tt>>=1)
			for(int j=0;j<len;j+=(i<<1))
				for(int k=j,t=len;k<(j|i);++k,t-=tt){
					int x=f[k],y=(ll)f[k|i]*cw[t]%P;
					if((f[k]=x+y)>=P) f[k]-=P;
					if((f[k|i]=x-y)<0) f[k|i]+=P;
				}
		for(int i=0;i<len;++i) f[i]=(ll)f[i]*ilen%P;
	}
	IL int size(){return f.size();}
	IL void reduce(){while(!f.empty()&&!f.back()) f.pop_back();}
	IL void rever(){reverse(ALL(f));}
	IL void show(){
		for(int x:f) printf("%d ",x);
		putchar('\n');
	}
	IL void trunc(int lim){
		if(lim<int(f.size())) f.erase(f.begin()+lim,f.end());
	}
	IL poly inv(int lim){ // mod x^lim
		assert(f[0]);
		poly cur({qp(f[0])});
		for(int t=1;t<lim;t<<=1){
			poly ff(t<<2);
			copy(f.begin(),f.begin()+min(t<<1,size()),ff.f.begin());
			init(t<<2);ff.NTT();cur.NTT();
			poly tmp(len);
			for(int i=0;i<len;++i){
				tmp[i]=(2ll-(ll)cur[i]*ff[i])%P*cur[i]%P;
				if(tmp[i]<0) tmp[i]+=P;
			}
			tmp.INTT();
			cur.f.swap(tmp.f);
			cur.trunc(t<<1);
		}
		cur.trunc(lim);
		return cur;
	}
	friend poly operator+(poly A,poly B){
		int mx=max(A.size(),B.size());
		A.f.resize(mx,0);B.f.resize(mx,0);
		poly C(mx);
		for(int i=0;i<mx;++i){
			C[i]=A[i]+B[i];
			if(C[i]>=P) C[i]-=P;
		}
		return C;
	}
	friend poly operator-(poly A,poly B){
		int mx=max(A.size(),B.size());
		A.f.resize(mx,0);B.f.resize(mx,0);
		poly C(mx);
		for(int i=0;i<mx;++i){
			C[i]=A[i]-B[i];
			if(C[i]<0) C[i]+=P;
		}
		C.reduce();
		return C;
	}
	friend poly operator*(poly A,poly B){
		init(A.size()+B.size()-1);A.NTT();B.NTT();
		poly C(len);
		for(int i=0;i<len;++i) C[i]=(ll)A[i]*B[i]%P;
		C.INTT();C.reduce();
		return C;
	}
	poly operator*(int X){
		int n=size();
		poly F(n);
		for(int i=0;i<n;++i) F[i]=(ll)f[i]*X%P;
		return F;
	}
	friend poly operator%(poly F,poly G){
		int n=F.size()-1,m=G.size()-1;
		if(n<m) return F;
		F.rever();G.rever();
		poly Q=G.inv(n-m+1);
		Q.prod(Q,F);Q.f.resize(n-m+1,0);
		F.rever();G.rever();Q.rever();
		poly R=F-Q*G;
		R.reduce();
		return R;
	}
	IL void prod(poly A,poly B){
		init(A.size()+B.size()-1);A.NTT();B.NTT();
		f.resize(len);
		for(int i=0;i<len;++i) f[i]=(ll)A[i]*B[i]%P;
		INTT();reduce();
	}
	IL void prodT(poly A,poly B){
		int an=A.size()-1,bn=B.size()-1;
		reverse(ALL(B.f));prod(A,B);
		for(int i=0;i<=an;++i) f[i]=f[i+bn];
		trunc(an+1);
	}
	IL int calc(int t){
		int pw=1,res=0;
		for(int x:f){
			res=(res+(ll)pw*x)%P;
			pw=(ll)pw*t%P;
		}
		return res;
	}
	IL poly deriv(){
		int n=f.size();
		poly D(n-1);
		for(int i=1;i<n;++i) D[i-1]=(ll)f[i]*i%P;
		return D;
	}
	IL poly integ(){
		int n=f.size();
		poly D(n+1),inv(n+1);
		for(int i=1;i<=n;++i){
			if(i>1) inv[i]=(ll)inv[P%i]*(P-P/i)%P;
			else inv[1]=1;
			D[i]=(ll)f[i-1]*inv[i]%P;
		}
		return D;
	}
	IL poly getln(int lim){ // mod x^lim
		assert(f[0]==1);
		poly F=deriv()*inv(lim);
		F.f.resize(lim-1,0);
		return F.integ();
	}
	IL poly getexp(int lim){ // mod x^lim
		assert(f[0]==0);
		poly F({1});
		for(int t=1;t<lim;t<<=1){
			poly ff(t<<1);
			copy(f.begin(),f.begin()+min(t<<1,size()),ff.f.begin());
			F=F*(poly({1})-F.getln(t<<1)+ff);
			F.f.resize(t<<1,0);
		}
		F.trunc(lim);
		return F;
	}
	IL poly sqrt(int lim){ // without quadratic residue , mod x^lim
		assert(f[0]==1);
		poly F({1});
		for(int t=1;t<lim;t<<=1){
			poly ff(t<<1);
			copy(f.begin(),f.begin()+min(t<<1,size()),ff.f.begin());
			F=(F+F.inv(t<<1)*ff)*((P+1)>>1);
			F.f.resize(t<<1,0);
		}
		F.trunc(lim);
		return F;
	}
};
const int N=200003;
int n;
int fac[N],fiv[N],pw[N];
void init_math(int lim){
	fac[0]=1;
	for(int i=1;i<=lim;++i) fac[i]=(ll)fac[i-1]*i%P;
	fiv[lim]=qp(fac[lim]);
	for(int i=lim;i;--i) fiv[i-1]=(ll)fiv[i]*i%P;
	pw[0]=1;
	for(int i=1;i<=lim;++i) (pw[i]=pw[i-1]<<1)>=P&&(pw[i]-=P);
}
int main(){
	init_math(1.1e5);
	n=read();
	poly F(n+1),G(n+1);
	for(int i=0;i<=n;++i) F[i]=fiv[i+1],G[i]=fiv[i];
	F=F.getln(n+1);
	F[0]=0;
	for(int i=1;i<=n;++i) F[i]=(ll)F[i]*qp(qp(2,i)-1)%P;
	F=F.getexp(n+1);
	G=F.inv(n+1)*G;
	G.f.resize(n+1);
	for(int i=0,coe=0,tt=1;i<=n;++i){
		int tmp=(ll)G[i]*tt%P;
		G[i]=(ll)coe*qp(2,P-1-(i*(i-1)>>1))%P;
		coe+=tmp;
		if(coe&1){
			if(coe<P) coe+=P;
			else coe-=P;
		}
		coe>>=1;
		tt=(ll)tt*pw[i]%P;
	}
	F=F*G;
	printf("%d\n",int((ll)F[n]*fac[n]%P));
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2ms
memory: 8532kb

input:

1

output:

499122177

result:

ok 1 number(s): "499122177"

Test #2:

score: 0
Accepted
time: 2ms
memory: 8736kb

input:

3

output:

561512450

result:

ok 1 number(s): "561512450"

Test #3:

score: 0
Accepted
time: 2ms
memory: 8776kb

input:

10

output:

609769250

result:

ok 1 number(s): "609769250"

Test #4:

score: 0
Accepted
time: 0ms
memory: 8744kb

input:

1000

output:

475714976

result:

ok 1 number(s): "475714976"

Test #5:

score: 0
Accepted
time: 5ms
memory: 8452kb

input:

1024

output:

178624793

result:

ok 1 number(s): "178624793"

Test #6:

score: -100
Time Limit Exceeded

input:

100000

output:


result: