QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#44318 | #4604. Shattrath City | Gemini7X | AC ✓ | 782ms | 11948kb | C++20 | 2.5kb | 2022-08-15 15:53:33 | 2022-08-15 15:53:35 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+5,mod=998244353;
int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
int dec(int a,int b){return a<b?a-b+mod:a-b;}
int mul(int a,int b){return 1ll*a*b%mod;}
int ksm(int a,int b=mod-2){int ret=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ret=mul(ret,a);return ret;}
int F[maxn],G[maxn],fac[maxn],ifac[maxn];
int gn[maxn],rev[maxn];
int N,M;
void initg(int len){
for(int i=1;i<len;i<<=1){
gn[i]=1;
gn[i+1]=ksm(3,(mod-1)/(i<<1));
for(int j=2;j<i;j++){
gn[i+j]=mul(gn[i+j-1],gn[i+1]);
}
}
}
void ntt(int *f,int len,int op){
for(int i=0;i<len;i++)if(i<rev[i])swap(f[i],f[rev[i]]);
for(int i=1;i<len;i<<=1){
for(int j=0;j<len;j+=i<<1){
for(int k=0;k<i;k++){
int x=f[j+k],y=mul(gn[i+k],f[j+k+i]);
f[j+k]=add(x,y);
f[j+k+i]=dec(x,y);
}
}
}
if(op==-1){
int Inv=ksm(len);
reverse(f+1,f+len);
for(int i=0;i<len;i++)f[i]=mul(f[i],Inv);
}
}
void poly_mul(int *f,int *g,int *h,int n,int m){
static int a[maxn],b[maxn];
int len=1,lg=0;
while(len<=n+m)len<<=1,lg++;
initg(len);
for(int i=0;i<len;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1));
for(int i=0;i<len;i++)a[i]=i<=n?f[i]:0;
for(int i=0;i<len;i++)b[i]=i<=m?g[i]:0;
ntt(a,len,1);ntt(b,len,1);
for(int i=0;i<len;i++)a[i]=mul(a[i],b[i]);
ntt(a,len,-1);
for(int i=0;i<len;i++)h[i]=i<=n+m?a[i]:0;
}
void cdq(int l,int r){
if(l==r){
G[l]=mul(add(F[l-1],G[l-1]),N);
if(l>=N)F[l]=dec(F[l],mul(add(F[l-N],G[l-N]),fac[N]));
return;
}
int mid=(l+r)>>1;
cdq(l,mid);
static int A[maxn],B[maxn],C[maxn];
for(int i=l;i<=mid;i++)A[i-l]=F[i];
for(int i=1;i<=min(N-1,r-l);i++)B[i]=fac[i];
poly_mul(A,B,C,mid-l,min(N-1,r-l));
for(int i=mid+1;i<=min(mid+min(N-1,r-l),r);i++)F[i]=dec(F[i],C[i-l]);
cdq(mid+1,r);
}
void MAIN(){
scanf("%d%d",&N,&M);
//N=100000,M=200000;
F[0]=0;G[0]=1;
for(int i=1;i<=M;i++)F[i]=G[i]=0;
fac[0]=1;
for(int i=1;i<N;i++){
fac[i]=mul(fac[i-1],i);
G[i]=mul(G[i-1],N);
}
fac[N]=mul(fac[N-1],N);
cdq(N,M);
printf("%d\n",add(F[M],G[M]));
}
void init(int mx){
fac[0]=ifac[0]=1;
for(int i=1;i<=mx;i++)fac[i]=mul(fac[i-1],i);
ifac[mx]=ksm(fac[mx]);
for(int i=mx-1;i;i--)ifac[i]=mul(ifac[i+1],i+1);
}
int main(){
int T;scanf("%d",&T);while(T--)MAIN();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 782ms
memory: 11948kb
input:
4 99999 199996 44353 200000 41592 199824 192608 199978
output:
425744116 51535034 430216206 653776337
result:
ok 4 lines