QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#360600 | #8329. Excuse | yyyyxh | TL | 5ms | 8776kb | C++14 | 5.9kb | 2024-03-21 22:23:55 | 2024-03-21 22:23:56 |
Judging History
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