• P4609 [FJOI2016]建筑师


    题面

    luogu

    前言

    这道题作为我们的考试题,蒟蒻我不透彻第一类斯大林数,就只打了个爆搜 10分滚粗。丢人。

    果然,我是这个机房最菜的。

    今天,就恶补一下第一类斯大林数。

    前置芝士

    1. 第一类斯大林数

    2. 组合数

    不会的童鞋,右转上边那篇博客,哪里有详细介绍。

    题解

    首先,一句话题意问我们前缀最大值为 \(A\) 且 后缀最大值为 \(b\) 的排列有几种。

    我们思考这样一个问题,最大的数 \(n\) 会把我们的序列分成两部分,

    前边就是我们的前缀最大值,后边就是我们的后缀最大值。(因为 \(n\) 是最大的数了,其他没有比他再大的了)

    也就是说,我们把 \(n\) 看做一个分水岭,他左边的被左边的挡住,右边的被右边的挡住。

    那我们把一个数以及被他挡住的一个数看成一个块。 \(n\)这个数看成独立的一块。

    引用下luogu 的图片

    每个块都由块内最大的数表示。

    那我们就需要把这 剩下的 \(n-1\) 个数 分到 \(A+B-2\) 个块中。

    这也就是第一类斯大林数 \(S_{n-1}^{A+B-2}\)

    我们把每个块填完之后,就要分是把这个块放到 \(n\) 的左边还是右边

    这就用到了组合数 \(C_{A+B-2}^{A-1}\)

    这个柿子的意思是,我们在 \(A+B-2\) 个块中 选 \(A-1\) 个块的方案数

    所以,最后的总柿子就是 \(S_{n-1}^{A+B-2} \times C_{A+B-2}^{A-1}\)

    第一类斯大林数可以通过它的递推式来求,组合数也可以用杨辉三角。

    最后的复杂度就是 \(O(A*n)+O(A*A)\) 的预处理,以及 O(1)的回答

    Code:

    #pragma GCC optimize(2) 
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int p = 1e9+7;
    int n,a,b,Q;
    long long s[50010][250],c[250][250];
    inline int read()
    {
    	int s = 0,w = 1; char ch = getchar();
    	while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9'){s =s * 10+ch - '0'; ch = getchar();}
    	return s * w;
    }
    void YYCH()//预处理第一类斯大林数和组合数
    {
    	s[0][0] = 1;
    	for(int i = 1; i <= 50000; i++)
    	{
    		for(int j = 1; j <= 240; j++)
    		{
    			s[i][j] = (s[i-1][j-1] + s[i-1][j] * (i-1) % p) % p;
    		}
    	}
    	c[0][0] = 1;
    	for(int i = 1; i <= 240; i++)
    	{
    		c[i][0] = 1;
    		for(int j = 1; j <= i; j++)
    		{
    			c[i][j] = (c[i-1][j-1] + c[i-1][j]) % p;
    		} 
    	}
    }
    int main()
    {
        Q = read(); YYCH();
        while(Q--)
        {
        	n = read(); a = read(); b = read();
        	long long ans = s[n-1][a+b-2] * c[a+b-2][a-1] % p;//回答
        	printf("%lld\n",ans);
        }
    	return 0;
    }
    

    总结

    考场上不会推也不要紧,自己打表找找规律。

    此外也可以用来和自己推到的柿子进行对拍。

    另外还有本题的加强版 CF960G Bandit Blues

    不过这题要用 NTT来写。

    但 Ame__ 大佬A了这道题 %%%。

  • 相关阅读:
    FZOJ2115+月赛+多项式
    Statistical Data Mining Tutorials [转]
    码农何去何从
    关于InnoDB索引长度限制的tips
    虚拟化、云计算、开放源代码及其他
    互联网开放平台应用综述
    2012.09月面试五十题
    linux运维常用命令
    Linux 性能测试与分析转
    "Principles of Computer Systems Design"
  • 原文地址:https://www.cnblogs.com/genshy/p/13571405.html
Copyright © 2020-2023  润新知