QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#408183#6411. Classical FFT Problemgrass8cowWA 3ms16284kbC++173.6kb2024-05-09 19:48:262024-05-09 19:48:27

Judging History

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

  • [2024-05-09 19:48:27]
  • 评测
  • 测评结果:WA
  • 用时:3ms
  • 内存:16284kb
  • [2024-05-09 19:48:26]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
#define vi vector<int>
#define pb push_back
const int mod=998244353,G=3,GI=(mod+1)/3;
int qpow(int a,int b){
	int c=1;for(;b;b>>=1){
		if(b&1)c=1ll*a*c%mod;
		a=1ll*a*a%mod;
	}
	return c;
}
int L,lb[1<<20];
void init(int n){
	L=1;while(L<=n)L<<=1;
	for(int i=0;i<L;i++)lb[i]=(lb[i>>1]>>1)|((i&1)?(L>>1):0);
}
void NTT(vi &a,int fl){
	for(int i=0;i<L;i++)if(i>lb[i])swap(a[i],a[lb[i]]);
	for(int o=1;o<L;o<<=1){
		int Wn=qpow(fl?G:GI,(mod-1)/(o<<1));
		for(int i=0;i<L;i+=(o<<1))for(int j=0,w=1;j<o;j++,w=1ll*w*Wn%mod){
			int x=a[i+j],y=1ll*w*a[i+j+o]%mod;
			a[i+j]=(x+y)%mod,a[i+j+o]=(x-y)%mod;
		}
	}
	if(!fl){
		int I=qpow(L,mod-2);
		for(int i=0;i<L;i++)a[i]=1ll*a[i]*I%mod;
	}
}
vi mul(vi a,vi b){
	int n=(int)a.size()+(int)b.size()-1;init(n);
	a.resize(L),b.resize(L),NTT(a,1),NTT(b,1);
	for(int i=0;i<L;i++)a[i]=1ll*a[i]*b[i]%mod;
	NTT(a,0);a.resize(n);
	return a;
}
vi mulT(vi a,vi b){
	//注意:第二个是常量!c_j=sum a_{i-j}b_j a_i=sum c_{i+j}b_{m-1-j}
	int n=a.size(),m=b.size();reverse(b.begin(),b.end());
	b=mul(a,b);
	for(int i=0;i<n;i++)a[i]=b[i+m-1];
	return a;
}
vi az[401000];
void cs(int p,int l,int r,vi &x){
	if(l==r){
		az[p].resize(2);
		az[p][0]=1,az[p][1]=-x[l];
		return;
	}
	int mid=(l+r)>>1;cs(p<<1,l,mid,x),cs(p<<1|1,mid+1,r,x);
	az[p]=mul(az[p<<1],az[p<<1|1]);
}
vi WT;
vi Inv(vi &a,int n){
	if(n==1)return vi(1,qpow(a[0],mod-2));
	vi b=Inv(a,(n+1)>>1);
	init(2*n);b.resize(L),WT.resize(L);
	for(int i=0;i<n;i++)WT[i]=a[i];
	for(int i=n;i<L;i++)WT[i]=0;
	NTT(WT,1),NTT(b,1);
	for(int i=0;i<L;i++)b[i]=1ll*b[i]*(2-1ll*b[i]*WT[i]%mod)%mod;
	NTT(b,0);b.resize(n);return b;
}
void Sol(int p,int l,int r,vi x,vi &y){
	x.resize(r-l+1);
	if(l==r){y[l]=x[0];return;}
	int mid=(l+r)>>1;
	Sol(p<<1,l,mid,mulT(x,az[p<<1|1]),y);
	Sol(p<<1|1,mid+1,r,mulT(x,az[p<<1]),y);
}
vi Qz(vi a,vi b,int n){
	a.resize(n+1),b.resize(n);
	vi c;cs(1,0,n-1,b);
	c.resize(n);
	Sol(1,0,n-1,mulT(a,Inv(az[1],n+1)),c);
	return c;
}
int a[(1<<17)+10],b[(1<<17)+10],jc[(1<<17)+10],ij[(1<<17)+10],n,t;
int C(int a,int b){
    if(a<0||b<0||a<b)return 0;
    return 1ll*jc[a]*ij[b]%mod*ij[a-b]%mod;
}
vi dcq(int l,int r){
    if(l==r)return {a[l],mod-1};
    int mid=(l+r)>>1;
    return mul(dcq(l,mid),dcq(mid+1,r));
}
int sol(int o){
    int ans=0;
    for(int j=0;j<=o;j++)(ans-=((j&1)?-1ll:1ll)*C(o,j)*qpow(t-j,t)%mod)%=mod;
    vi az=dcq(1,t),za;
    for(int j=0;j<=o;j++)za.pb(j);
    vi c=Qz(az,za,t+1);
    for(int j=0;j<=o;j++){
        int an=((j&1)?-1:1)*C(o,j)*c[j]%mod;
        (ans+=an)%=mod;
    }
    return ans;
    //要求至少有一个搞到上面的部分
}
int calc(int x){
    int s=0;
    for(int i=0;i<=x;i++)
    (s+=((i&1)?-1ll:1ll)*C(x,i)*qpow(t-i,t)%mod)%=mod;
    return s;
}
int main(){
    scanf("%d",&n);
    jc[0]=1;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),jc[i]=1ll*i*jc[i-1]%mod;
    ij[n]=qpow(jc[n],mod-2);
    for(int i=n;i;i--)ij[i-1]=1ll*i*ij[i]%mod;
    reverse(a+1,a+n+1);
    if(a[n]==n){
        int ans=qpow(n,n)*2%mod;(ans-=jc[n])%=mod;
        printf("%d %d\n",n,(ans+mod)%mod);
        return 0;
    }
    t=1;while(a[t]>=t)t++;t--;
    printf("%d ",t);
    int ans=0;
    int o1=a[t+1];
    (ans+=sol(o1))%=mod;
    for(int i=t;i<=n;i++)for(int j=a[i+1]+1;j<=min(a[i],t);j++)b[j]=i;
    int o2=0;
    for(int i=1;i<=t;i++)if(a[i]>t)o2=i;
    for(int i=1;i<=t;i++)a[i]=b[i];
    (ans+=sol(o2))%=mod;
    (ans+=calc(o1))%=mod,(ans+=calc(o2))%=mod,(ans-=jc[t])%=mod;
    return printf("%d",(ans+mod)%mod),0;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 14016kb

input:

3
1 2 3

output:

2 6

result:

ok 2 number(s): "2 6"

Test #2:

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

input:

1
1

output:

1 1

result:

ok 2 number(s): "1 1"

Test #3:

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

input:

2
1 1

output:

1 2

result:

ok 2 number(s): "1 2"

Test #4:

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

input:

2
2 2

output:

2 6

result:

ok 2 number(s): "2 6"

Test #5:

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

input:

3
1 1 1

output:

1 3

result:

ok 2 number(s): "1 3"

Test #6:

score: 0
Accepted
time: 3ms
memory: 16068kb

input:

3
2 2 2

output:

2 9

result:

ok 2 number(s): "2 9"

Test #7:

score: 0
Accepted
time: 3ms
memory: 16280kb

input:

3
3 3 3

output:

3 48

result:

ok 2 number(s): "3 48"

Test #8:

score: 0
Accepted
time: 3ms
memory: 16284kb

input:

5
1 1 3 3 4

output:

3 47

result:

ok 2 number(s): "3 47"

Test #9:

score: -100
Wrong Answer
time: 3ms
memory: 16052kb

input:

10
2 4 5 5 5 5 6 8 8 10

output:

5 696255333

result:

wrong answer 2nd numbers differ - expected: '864', found: '696255333'