QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#121685 | #6410. Classical DP Problem | SolitaryDream# | WA | 0ms | 40536kb | C++20 | 6.1kb | 2023-07-08 17:40:00 | 2023-07-08 17:40:01 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+1e3+7,P=998244353,g=3;
int qpow(int a,int b)
{
int ret=1;
while(b)
{
if(b&1)
ret=1ll*ret*a%P;
b>>=1;
a=1ll*a*a%P;
}
return ret;
}
int n,a[N],b[N];
int fac[N],inv[N];
void dft(int *a,int n,int f)
{
static int rev[N],ww[N],iw[N],pn=0;
if(pn!=n)
{
int p=qpow(g,(P-1)/n);
ww[0]=1;
for(int i=1;i<=n-1;i++)
ww[i]=ww[i-1]*p%P;
iw[n-1]=qpow(ww[n-1],P-2);
for(int i=n-1;i>=1;i--)
iw[i-1]=iw[i]*p%P;
for(int i=0;i<n;i++)
rev[i]=(rev[i>>1]>>1)|((i&1)*(n>>1));
pn=n;
}
int *w=f>0?ww:iw;
for(int i=0;i<n;i++)
if(rev[i]<i)
swap(a[rev[i]],a[i]);
for(int l=2;l<=n;l<<=1)
for(int *p=a;p!=a+n;p+=l)
for(int i=0,m=l>>1;i<m;i++)
{
int t=p[i+m];
p[i+m]=(p[i]+w[n/l*(i+m)]*t)%P;
p[i]=(p[i]+w[n/l*i]*t)%P;
}
if(f<0)
{
int t=qpow(n,P-2);
for(int i=0;i<n;i++)
a[i]=a[i]*t%P;
}
}
void Poly_Mul(const int *A,int LenA,const int *B,int LenB,int *C)
{
static int a[N],b[N];
int n=1;for(;n<LenA+LenB;n<<=1);
for(int i=0;i<n;i++)
a[i]=b[i]=0;
for(int i=0;i<LenA;i++)
a[i]=A[i];
for(int i=0;i<LenB;i++)
b[i]=B[i];
dft(a,n,1);
dft(b,n,1);
for(int i=0;i<n;i++)
C[i]=a[i]*b[i]%P;
dft(C,n,-1);
}
void Poly_Inv(const int *A,int LenA,int *B)
{
static int a[N],b[N];
B[0]=qpow(A[0],P-2);
for(int l=2;(l>>1)<LenA;l<<=1)
{
int n=l<<1;
for(int i=0;i<n;i++)
a[i]=b[i]=0;
for(int i=l>>1;i<l;i++)
B[i]=0;
for(int i=0;i<(l>>1)-1;i++)
a[i]=B[i];
for(int i=0;i<l;i++)
b[i]=A[i];
dft(a,n,1),dft(b,n,1);
for(int i=0;i<n;i++)
a[i]=a[i]*a[i]%P*b[i]%P;
dft(a,n,-1);
for(int i=0;i<l;i++)
b[i]=((b[i]<<1)-a[i])%P;
}
}
void Poly_Div(const int *A,int LenA,const int *B,int LenB,int *C,int *D)
{
static int a[N],b[N],c[N];
if(LenA<LenB)
{
for(int i=0;i<LenA;i++)
D[i]=A[i];
return;
}
int l=LenA-LenB+1;
for(int i=0;i<l;i++)
a[i]=b[i]=c[i]=0;
for(int i=0;i<LenA;i++)
a[i]=A[LenA-1-i];
for(int i=0;i<LenB;i++)
b[i]=B[LenB-1-i];
Poly_Inv(b,l,c);
Poly_Mul(a,l,c,l,b);
for(int i=0;i<l;i++)
C[i]=b[l-1-i];
Poly_Mul(B,LenB,C,l,a);
for(int i=0;i<LenB-1;i++)
D[i]=(A[i]-a[i]+P)%P;
}
namespace Evaluation{
const int V=N*30;
int a[N],b[N],c[N],d[N];
int mem[V],*loc;
int *g[N<<1],*h[N<<1];
void init(int L,int R,int p)
{
if(L==R)
{
g[p]=loc;
loc+=2;
g[p][0]=-b[L];
g[p][1]=1;
return;
}
int mid=(L+R)>>1;
init(L,mid,p<<1);
init(mid+1,R,p<<1|1);
g[p]=loc;
loc+=R-L+2;
Poly_Mul(g[p<<1],mid-L+2,g[p<<1|1],R-mid+1,g[p]);
}
void calc(int L,int R,int p)
{
if(L==R)
{
c[L]=h[p][0];
return;
}
int mid=(L+R)>>1;
h[p<<1]=loc;
loc+=mid-L+1;
Poly_Div(h[p],R-L+1,g[p<<1],mid-L+2,d,h[p<<1]);
calc(L,mid,p<<1);
h[p<<1|1]=loc;
loc+=R-mid;
Poly_Div(h[p],R-L+1,g[p<<1|1],R-mid+1,d,h[p<<1|1]);
calc(mid+1,R,p<<1|1);
}
void solve(const int *A,int n,const int *B,int m,int *C)
{
loc=mem;
for(int i=0;i<n;i++)
a[i]=A[i];
for(int i=0;i<m;i++)
b[i]=B[i];
init(0,m-1,1);
h[1]=loc;
loc+=m;
for(int i=0;i<m;i++)
h[1][i]=0;
Poly_Div(a,n,g[1],m+1,d,h[1]);
calc(0,m-1,1);
for(int i=0;i<m;i++)
C[i]=(c[i]+P)%P;
}
}
int k;
int calc(int *a,int x)
{
int ret=1;
for(int i=1;i<=k;i++)
ret=1ll*ret*(a[i]-x)%P;
return ret;
}
int A[N],B[N],tmp[N];
using poly=vector<int>;
poly solve(int l,int r)
{
if(l==r)
{
return {P-1,A[l]};
}
int mid=(l+r)>>1;
auto a=solve(l,mid);
auto b=solve(mid+1,r);
Poly_Mul(a.data(),a.size(),b.data(),b.size(),tmp);
poly ret;
for(int i=0;i<a.size()+b.size()-1;i++)
ret.push_back(tmp[i]);
return ret;
}
int val[N];
signed main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
reverse(a+1,a+n+1);
for(int i=1;i<=n;i++)
b[a[i]]++;
for(int i=n;i>=1;i--)
b[i]+=b[i+1];
k=1;
for(int i=2;i<=n+1;i++)
if(a[i]<i||b[i]<i)
{
k=i-1;
break;
}
int ans=0;
fac[0]=1;
for(int i=1;i<=k;i++)
fac[i]=1ll*fac[i-1]*i%P;
inv[k]=qpow(fac[k],P-2);
for(int i=k-1;i>=0;i--)
inv[i]=1ll*inv[i+1]*(i+1)%P;
// int t=a[k+1];
// for(int i=0;i<=t;i++)
// ans=(ans+1ll*(i&1?P-1:1)*fac[t]%P*inv[i]%P*inv[t-i]%P*calc(a,i))%P;
int t=a[k+1];
for(int i=1;i<=t;i++)
A[i]=a[i];
auto res=solve(1,t);
vector<int>x(t+1);
for(int i=0;i<=t;i++)
x[i]=i;
Evaluation::solve(res.data(),res.size(),x.data(),x.size(),val);
for(int i=0;i<=t;i++)
ans=(ans+1ll*(i&1?P-1:1)*fac[t]%P*inv[i]%P*inv[t-i]%P*val[i])%P;
// t=b[k+1];
// for(int i=0;i<=t;i++)
// ans=(ans+1ll*(i&1?P-1:1)*fac[t]%P*inv[i]%P*inv[t-i]%P*calc(b,i))%P;
t=b[k+1];
for(int i=1;i<=t;i++)
A[i]=b[i];
res=solve(1,t);
x.clear();
x.resize(t+1);
for(int i=0;i<=t;i++)
x[i]=i;
Evaluation::solve(res.data(),res.size(),x.data(),x.size(),val);
for(int i=0;i<=t;i++)
ans=(ans+1ll*(i&1?P-1:1)*fac[t]%P*inv[i]%P*inv[t-i]%P*val[i])%P;
ans=(ans-fac[k]+P)%P;
printf("%lld %lld\n",k,ans);
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 40536kb
input:
3 1 2 3
output:
2 998244345
result:
wrong answer 2nd numbers differ - expected: '6', found: '998244345'