• 2020CCPC秦皇岛H.Holy Sequence


    题目

    好久没写题解了,做了个计数感觉有点妙妙,就来口胡一波。

    由于我们要对于每一个(t)单独计算答案,所以必然要先枚举(t),考虑一个(n)-holy序列的前缀最大值每次最多只能增加(1),必然可以化为(1......2......3......4......5.......t)的形式。我们枚举(t)第一次出现的位置为(i)(i)前面的方案数可以用一个dp预处理出来。观察这个dp的转移发现其实就是第二类斯特林数

    这样(t)出现的位置必然在(i)以及(i)之后,考虑一个经典的恒等式(x^2=2 imes inom{x}{2}+inom{x}{1})。以计算(inom{x}{2})为例,我们完全可以钦定两个位置填(t),其余位置构成一个合法序列即可算贡献即可,而注意到我们钦定了(i)(t),那么(i)之后的位置填(t)都是合法的,所以我们其实并不是很关心这两个位置到底在哪里,在(i)后面用组合数随便钦定两个位置即可。

    最后还需要求出(i)(t)后面的合法方案数,发现从(i)填到(n)需要强行从(t)开始难以处理,于是考虑从(n)倒着向(i)搞一个dp,这样数是从大到小的,并不需要强行令(t)作为开头。

    预处理第二类斯特林数和这个反向的(dp),就能(O(n))回答一个(t)的答案了。

    代码

    #include<bits/stdc++.h>
    #define re signed
    const int maxn=3005;
    int n,mod,g[maxn][maxn],h[maxn][maxn];
    inline int qm(int x) {return x>=mod?x-mod:x;}
    inline int calc(int x) {return (1ll*x*(x-1)/2ll)%mod;}
    int main() {
    	int Test;scanf("%d",&Test);
    	for(re int te=1;te<=Test;++te) {
    		scanf("%d%d",&n,&mod);
    		for(re int i=0;i<=n+1;++i)
    			for(re int j=0;j<=n+1;++j)g[i][j]=h[i][j]=0;
    		g[0][0]=1;
    		for(re int i=0;i<n;i++)
    			for(re int j=0;j<=i;++j) {
    				if(!g[i][j]) continue;
    				g[i+1][j+1]=qm(g[i+1][j+1]+g[i][j]);
    				g[i+1][j]=qm(g[i+1][j]+1ll*g[i][j]*j%mod);
    			}
    		for(re int i=1;i<=n;i++)h[0][i]=1;
    		for(re int i=0;i<n;i++)
    			for(re int j=n;j;--j) {
    				if(!h[i][j]) continue;
    				h[i+1][j]=qm(h[i+1][j]+1ll*h[i][j]*j%mod);
    				if(j-1>0) h[i+1][j-1]=qm(h[i+1][j-1]+h[i][j]);
    			}
    		printf("Case #%d:
    ",te);
    		for(re int t=1;t<=n;++t) {
    			int ans=0;
    			for(re int i=1;i<=n;i++) {
    				if(!g[i-1][t-1]) continue;
    				int tot=h[n-i][t];
    				if(n-i-1>=0) tot=qm(tot+3ll*h[n-i-1][t]%mod*(n-i)%mod);
    				if(n-i-2>=0) tot=qm(tot+2ll*h[n-i-2][t]%mod*calc(n-i)%mod);
    				ans=qm(ans+1ll*tot*g[i-1][t-1]%mod);
    			}
    			printf("%d ",ans);
    		}
    		puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    mybatis
    队列
    JDK中的Timer和TimerTask详解
    NIOGoodDemo
    24-C#笔记-异常处理
    23-C#笔记-正则表达式
    22-C#笔记-预编译指令
    21-C#笔记-名称空间
    20-C#笔记-接口
    19-C#笔记-多态性
  • 原文地址:https://www.cnblogs.com/asuldb/p/15487030.html
Copyright © 2020-2023  润新知