其他分享
首页 > 其他分享> > [atAGC055F]Creative Splitting

[atAGC055F]Creative Splitting

作者:互联网

考虑判定序列$\{b_{i}\}$是否"amazing",从后往前拆分,即等价于如下问题:

初始$c_{i}$均为$k$(长度为$n$),从大到小枚举$i$并选择$c_{j}\ge b_{i}$减1,判定最终能否使$c_{i}$均为0

关于这个问题,可以贪心选择最小的$c_{j}$操作,证明如下:

注意到$c_{i}$是无序的,即$c_{x}=c_{y}$时操作$x$和$y$是等价的

引理:对于任意有解的$c_{i}$,贪心操作一次后仍有解

假设贪心操作$x$而某组解操作$y$,若$c_{x}=c_{y}$即得证,否则也即有$c_{x}<c_{y}$

为了方便,强制该组解在$c_{x}=c_{y}$时不操作$y$(操作$x$等价),即恒有$c_{x}\le c_{y}$

构造:操作$x$后模仿该组解操作,仅将下一次操作$x$改为操作$y$

考虑构造的合法性,分为三部分:

1.下一次操作$x$之前,注意到仅有$c_{x}$较小,显然成立

2.下一次操作$x$时,由于恒有$c_{x}\le c_{y}$,即在该组解中改为操作$c_{y}$也合法,进而与1.相同

3.下一次操作$x$之后,两者$c_{i}$均相同,显然成立

综上,再根据引理归纳即得证

同时,上述贪心也等价于不断选择最小的$j$操作(归纳$c_{1}\le c_{2}\le ...\le c_{n}$即可证明)

显然操作方式唯一,不妨枚举操作方式(即每一次操作的$j$)并统计序列数:

操作$c_{j}$时对应的$b_{i}$范围为$(c_{j-1},c_{j}]$,即有$c_{j}-c_{j-1}$种方式将$c_{j}$​减1

换言之,将每一次(操作前)的$c_{j}-c_{j-1}$相乘后即为序列数(特别的,约定$c_{0}=0$)

 

进一步的,考虑这样一个构造:

有$n+1$个格子(编号为$[0,n]$),初始$0$上有$k$个球(编号为$[1,k]$),每次操作将一个球向右移动一格,执行此操作$nk$次使所有球均在$n$上的所有方案

记$c_{i}$为$[0,i)$这些格子上球的数量,初始$c_{i}$均为$k$,将$i$上的球向右移动即将$c_{i}$减1,且有$c_{i}-c_{i-1}$种方式,最终使得$c_{i}$均为0的所有方案

不难发现,这与amazing的序列计数是相同的,不妨考虑这个构造的问题:

不考虑$b_{pos}=val$的限制,显然这个问题的答案(也即amazing的序列总数)为${nk\choose n,n,...,n}$(共$k$个$n$)

关于$b_{pos}=val$的限制,对应于此问题中,即第$nk-pos+1$次操作必须选择第$val$个球操作(从左向右数,同一个格子内的球按照编号从小到大排序)

枚举对应的位置$i$,再枚举$i$左侧/上/右侧的球数量$x,y$和$z$(要求$x+y+z=k$且$x<val\le x+y$),选择球的方案数即${k\choose x,y,z}$,同时操作的方案数即
$$
\sum_{\begin{array}&u_{1},u_{2},...,u_{x}<i\\v_{1},v_{2},...,v_{z}>i\\\sum u_{j}+\sum v_{j}+iy=nk-pos\end{array}}
{nk-pos\choose u_{j},v_{j},i,i,...,i}
{pos-1\choose n-u_{j},n-v_{j},n-i-1,n-i,n-i,....,n-i}
$$
(其中左侧$i$的数量为$y$,右侧$n-i$的数量为$y-1$)

将累加的部分展开,提取常数项后也即$\prod_{j=1}^{x}\frac{1}{u_{j}!(n-u_{j})!}\prod_{j=1}^{z}\frac{1}{v_{j}(n-v_{j})!}$

用$f_{i,j,k}$表示选择$j$个$[0,i)$之间的数$x$和为$k$的$\prod \frac{1}{x!(n-x)!}$​之和,进而该式也即
$$
\sum_{s=0}^{(i-1)x}f_{i,x,s}f_{n-i,y,s+iy+nz-nk+pos}
$$
关于$f_{i,j,k}$​的转移,考虑枚举最后一个数,显然即
$$
f_{i,j,k}=\sum_{x=0}^{i-1}\frac{f_{i,j-1,k-x}}{x!(n-x)!}
$$
预处理$f_{i,j,k}$的复杂度为$o(n^{3}k^{2})$,对于确定的$pos$和$val$计算$f(pos,val)$的复杂度为$o(n^{2}k^{3})$,由于有$n^{2}k$组,因此总复杂度为$o(n^{4}k^{4})$,无法通过

进一步的,注意到$s$的枚举中,后式仅取决于$i,x,z$和$iy+nz-nk+pos$,预处理复杂度为$o(n^{3}k^{4})$,然后即可$o(1)$求出,单次复杂度降为$o(nk^{2})$,总复杂度降为$o(n^{3}k^{4})$(预处理),可以通过

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 25
 4 #define M 405
 5 #define ll long long
 6 int n,m,mod,fac[M],inv[M],mi[N][N],f[N][N][M<<1],g[N][N][N][M<<1];
 7 int calc(int pos,int val){
 8     int ans=0;
 9     for(int i=0;i<n;i++)
10         for(int x=0;x<val;x++)
11             for(int y=val-x;x+y<=m;y++){
12                 int z=m-x-y,d=i*y+n*z-n*m+pos,s=g[i][x][z][d+n*m];
13                 s=(ll)s*fac[m]%mod*inv[x]%mod*inv[y]%mod*inv[z]%mod;
14                 s=(ll)s*mi[i][y]%mod*mi[n-i][y-1]%mod;
15                 s=(ll)s*fac[n*m-pos]%mod*fac[pos-1]%mod*inv[n-i-1]%mod;
16                 ans=(ans+s)%mod;
17             }
18     return ans;
19 }
20 int main(){
21     scanf("%d%d%d",&n,&m,&mod);
22     fac[0]=inv[0]=inv[1]=1;
23     for(int i=1;i<M;i++)fac[i]=(ll)fac[i-1]*i%mod;
24     for(int i=2;i<M;i++)inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
25     for(int i=1;i<M;i++)inv[i]=(ll)inv[i-1]*inv[i]%mod;
26     for(int i=0;i<=n;i++){
27         mi[i][0]=1;
28         for(int j=1;j<=m;j++)mi[i][j]=(ll)mi[i][j-1]*inv[i]%mod;
29     }
30     for(int i=0;i<=n;i++)f[i][0][0]=1;
31     for(int i=1;i<=n;i++)
32         for(int j=1;j<=m;j++)
33             for(int k=0;k<=n*m;k++)
34                 for(int x=0;x<i;x++)
35                     if (x<=k)f[i][j][k]=(f[i][j][k]+(ll)inv[x]*inv[n-x]%mod*f[i][j-1][k-x])%mod;
36     for(int i=0;i<n;i++)
37         for(int x=0;x<=m;x++)
38             for(int z=0;x+z<=m;z++)
39                 for(int d=-n*m;d<=n*m;d++){
40                     int ans=0;
41                     for(int s=max(-d,0);s<=(i-1)*x;s++)ans=(ans+(ll)f[i][x][s]*f[n-i][z][s+d])%mod;
42                     g[i][x][z][d+n*m]=ans;
43                 }
44     for(int pos=1;pos<=n*m;pos++){
45         for(int val=1;val<=m;val++)printf("%d ",calc(pos,val));
46         putchar('\n');
47     }
48     return 0;
49 } 
View Code

 

标签:nk,复杂度,pos,Splitting,枚举,le,操作,Creative,atAGC055F
来源: https://www.cnblogs.com/PYWBKTDA/p/15674590.html