• [省选联考 2020 A 卷] 组合数问题


    题面

    题解

    (F(n, m) = sum_{k=0}^n k^mx^kinom nk),于是答案就是 (sum_i a_iF(n, i))

    那么有:

    [egin{aligned} F(n, m) &= sum_{k=0}^n k^m x^k inom nk\ &= nsum_{k=0}^n k^{m-1}x^kinom {n-1}{k-1} end{aligned} ]

    然后:

    [egin{aligned} F(n, m) &= sum_{k=0}^n k^mx^kinom nk\ &= sum_{k=0}^n k^mx^kleft(inom {n-1}k + inom{n-1}{k-1} ight)\ &= F(n-1,m) + frac 1n F(n, m + 1) end{aligned} ]

    也就是说:(F(n, m) = n(F(n, m - 1) - F(n - 1, m - 1)))

    边界为 (F(n, 0) = (x + 1)^n)

    代码

    #include <bits/stdc++.h>
    
    inline int read()
    {
    	int data = 0, w = 1; char ch = getchar();
    	while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    	if (ch == '-') w = -1, ch = getchar();
    	while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
    	return data * w;
    }
    
    const int N(1010);
    int n, x, P, m, f[N], g[N], a[N];
    int fastpow(int x, int y)
    {
    	int ans = 1;
    	for (; y; y >>= 1, x = 1ll * x * x % P)
    		if (y & 1) ans = 1ll * ans * x % P;
    	return ans;
    }
    
    int main()
    {
    	n = read(), x = read(), P = read(), m = read();
    	for (int i = 0; i <= m; i++) a[i] = read();
    	f[0] = fastpow(x + 1, n - m);
    	for (int i = m - 1; ~i; i--)
    	{
    		g[0] = 1ll * f[0] * (x + 1) % P;
    		for (int j = 1; j <= m - i; j++)
    			g[j] = 1ll * (g[j - 1] - f[j - 1] + P) % P * (n - i) % P;
    		for (int j = 0; j <= m - i; j++) f[j] = g[j];
    	}
    	int ans = 0;
    	for (int i = 0; i <= m; i++) ans = (ans + 1ll * f[i] * a[i]) % P;
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    bzoj2815: [ZJOI2012]灾难
    bzoj1188: [HNOI2007]分裂游戏
    bzoj4538: [Hnoi2016]网络
    bzoj3594: [Scoi2014]方伯伯的玉米田
    bzoj2595: [Wc2008]游览计划
    bzoj3277: 串
    Django开发:(3.2)ORM:多表操作
    Django开发:(3.1)ORM:单表操作
    Django:(2)视图层&模板层
    Django开发:(1)django基础 & url控制器
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/13198301.html
Copyright © 2020-2023  润新知