• bzoj[2655] calc


    Description

      一个序列a1,...,an是合法的,当且仅当:
      长度为给定的n。
      a1,...,an都是[1,A]中的整数。
      a1,...,an互不相等。
      一个序列的值定义为它里面所有数的乘积,即a1a2...an。
      求所有不同合法序列的值的和。
      两个序列不同当且仅当他们任意一位不一样。
      输出答案对一个数mod取余的结果。

    Input

      一行3个数,A,n,mod。意义为上面所说的。

    Output

      一行结果。

    Sample Input

    9 7 10007

    Sample Output

    3611

    HINT

    数据规模和约定

      0:A<=10,n<=10。

      1..3:A<=1000,n<=20.

      4..9:A<=10^9,n<=20

      10..19:A<=10^9,n<=500。

      全部:mod<=10^9,并且mod为素数,mod>A>n+1

     Solution

    可以得出一个时间复杂度爆炸的dp方程

    f[i][j] = f[i - 1][j - 1] * j + f[i - 1][j]

    f[i][j]表示从区间[1,j]中选出i个数得出的序列的乘积和

    所以把算出500递推值,之后用lagrange插值拟合多项式,再把A带进去求值就好

    #include <stdio.h>
    typedef long long ll;
    int m, n, p, tot;
    ll f[1510][510], fac[510], x[1010], y[1010];
    ll Pow(register ll t, register int k)
    	{
    	register ll tmp = 1;
    	for(; k; k >>= 1, t = t * t % p) if(k & 1) tmp = tmp * t % p;
    	return tmp;
    	}
    ll Lagrange()
    	{
    	ll ans = 0, a = 1, b;
    	for(register int i = 0; i < tot; i++) a = a * (m - x[i] + p) % p;
    	for(register int i = 0; i < tot; ans = (ans + a * Pow(b, p - 2) % p * y[i]) % p, i++)
    		{
    		b = (m - x[i] + p) % p;
    		for(register int j = 0; j < tot; j++) if(i != j) b = b * (x[i] - x[j] + p) % p;
    		}
    	return ans;
    	}
    int main()
    	{
    	scanf("%d%d%d", &m, &n, &p);
    	fac[0] = 1; for(register int i = 1; i <= n; i++) fac[i] = fac[i - 1] * i % p;
    	f[0][0] = 1; for(register int i = 1; i <= n * 3 + 5; i++)
    					for(register int j = 0; j <= n + 5; j++)
    					 	f[i][j] = j ? (f[i - 1][j - 1] * i + f[i - 1][j]) % p : f[i - 1][j];
    	for(register int i = 1; tot <= (n << 1 | 1); i++)
    		if(f[i][n] && i ^ m) x[tot] = i, y[tot++] = f[i][n];
    	printf("%lld
    ", Lagrange() * fac[n] % p);
    	return 0;
    	}
    

      

  • 相关阅读:
    BZOJ1057:[ZJOI2007]棋盘制作——题解
    洛谷4147:玉蟾宫——题解
    洛谷1578:[WC2002]奶牛浴场——题解
    BZOJ1926:[SDOI2010]粟粟的书架——题解
    BZOJ3123:[SDOI2013]森林——题解
    BZOJ1834:[ZJOI2010]网络扩容——题解
    BZOJ2668:[CQOI2012]交换棋子——题解
    BZOJ1070:[SCOI2007]修车——题解
    BZOJ1877:[SDOI2009]晨跑——题解
    在阿里,我们如何管理测试环境
  • 原文地址:https://www.cnblogs.com/keshuqi/p/6659397.html
Copyright © 2020-2023  润新知