题解 P4566 [CTSC2018]青蕈领主
显然若将每个
具体而言,区间 1 1 ... 1 n+1 问题的答案
利用递归的结构,设
设
接下来只需要求
由
分治 FFT 即可。时间复杂度
代码
常数超大
upd:减小了常数
long long F[N],G[N],P[N],Q[N];
long long A[N],B[N];
void Devide_solve(long long l,long long r){
if(l==r){
G[l]=(mod-G[l])%mod;
P[l]=(l+1)*G[l]%mod;
if(l>1) Q[l]=l*G[l]%mod;
return ;
}
long long mid=(l+r)>>1ll;
Devide_solve(l,mid);
long long lim=r-l+1,len=lim>>1ll;
if(l==1){
for(long long i=1;i<=len;i++) A[i]=(P[i]+Q[i+1])%mod;
for(long long i=1;i<=len;i++) B[i]=G[i];
NTT::solve(A,A,B,len,len);
for(long long i=len+1;i<=lim;i++){
int t=i-len+mid;
G[t]=(G[t]+A[i])%mod;
}
}
else{
for(long long i=1;i<=len;i++) A[i]=P[l+i-1];
for(long long i=0;i<=len;i++) A[i]=(A[i]+Q[l+i])%mod;
for(long long i=1;i<=lim;i++) B[i]=G[i];
NTT::solve(A,A,B,len,lim);
for(long long i=len+1;i<=lim;i++){
int t=i-len+mid;
G[t]=(G[t]+A[i])%mod;
}
for(long long i=1;i<=len;i++) A[i]=G[l+i-1];
for(long long i=1;i<=lim;i++) B[i]=(P[i]+Q[i+1])%mod;
NTT::solve(A,A,B,len,lim);
for(long long i=len+1;i<=lim;i++){
int t=i-len+mid;
G[t]=(G[t]+A[i])%mod;
}
}
Devide_solve(mid+1,r);
}
long long T,n,ans;
long long a[N];
void solve(long long l,long long r){
if(a[r]!=r-l+1) ans=0;
if(l==r) return ;
long long mx=r,tot=0;
for(long long i=r-1;i>=l;i--){
if(i<mx){
mx=i-a[i]+1;
solve(mx,i);
tot++;
}
else if(i-a[i]+1<mx) ans=0;
}
ans=ans*F[tot]%mod;
}
int main(){
pre();
cin>>T>>n;
G[1]=mod-1;
long long lim=NTT::init(n,0);
long long m=1ll<<lim;
Devide_solve(1,m);
for(long long i=0;i<n;i++) F[i]=G[i+1];
INV::solve(F,F,n);
while(T--){
for(long long i=1;i<=n;i++) scanf("%lld",&a[i]);
ans=1;
solve(1,n);
printf("%lld\n",ans);
}
}