终于做出了这个把我送退役的结论题。
由于是均匀混合,所以所有排列出现的概率相同。
考场上我写了30分的O(mn^2)暴力,然后发现:E[ai]仍然为一次、二次函数。这个可以用期望的线性性解释。
定义E[ai]=f(i),f(i)为关于i的一/二次函数,然后经过操作为k的变化,左边第i项变成f(i),右边第i项变成f(k+i),然后求出左边、右边(用插值)前三项即可。
#include<bits/stdc++.h> typedef long long ll; const int mod=998244353,inv2=499122177; int n,m,A,Q,tp; int E1, E2, E3; ll i0,i1,i2; int qpow(int a,int b) { int ret=1; while(b) { if(b&1)ret=1ll*ret*a%mod; a=1ll*a*a%mod,b>>=1; } return ret; } int calc(int i) { if(i==1)return E1; if(i==2)return E2; if(i==3)return E3; int s1=1ll*E1*(i-2)%mod*(i-3)%mod,s2=1ll*E2*(2-2*i+mod)%mod*(i-3)%mod,s3=1ll*E3*(i-1)%mod*(i-2)%mod; return(1ll*s1+s2+s3)*inv2%mod; } int main() { scanf("%d%d%d",&n,&m,&tp),--tp; i0=qpow(n,mod-2),i1=qpow(1ll*n*(n-1)%mod,mod-2),i2=qpow(1ll*n*(n-1)%mod*(n-2)%mod,mod-2); E1=1,E2=tp?4:2,E3=tp?9:3; while(m--) { scanf("%d",&A); ll f1=E1,f2=E2,f3=E3,f4=calc(A+1),f5=calc(A+2),f6=calc(A+3); E1=(f1*A+f4*(n-A))%mod*i0%mod; E2=(f2*A%mod*(A-1)+(f1+f4)*A%mod*(n-A)+f5*(n-A)%mod*(n-A-1))%mod*i1%mod; E3=(f3*A%mod*(A-1)%mod*(A-2)+(f4+2*f2)*A%mod*(A-1)%mod*(n-A)+(2*f5+f1)*A%mod*(n-A)%mod*(n-A-1)%mod+f6*(n-A)%mod*(n-A-1)%mod*(n-A-2))%mod*i2%mod; } scanf("%d",&Q); int X;while(Q--)scanf("%d",&X),printf("%d ",calc(X)); }