zoukankan      html  css  js  c++  java
  • BZOJ 2655 calc

    拉格朗日插值优化dp。

    显然可以得到(dp) :

    (f[i][j] = f[i - 1][j - 1] imes j + f[i][j-1])

    表示前(i)个数用([1,j])且单增的(ans), 题目要求的即为(f[n][A] imes n!)

    (f(n,j))转移时 有(f(n,j) - f(n, j-1)= f(n -1 , j - 1) imes j)

    引用结论 : (g(x))是关于(x)(n)次多项式的情况下 (g(x) - g(x-1))(n-1)次多项式

    形象点说就是(x^n - y^n = (x-y)sum{x^ky^{n-1-k}})

    (f(n,j))(p(n)) 次多项式 那么

    等式左边是 (p(n)-1)次多项式 右边是(p(n-1) + 1)次多项式

    得到(p(n) = 2n)

    所以(f)可以用一个(2n+1)次多项式表示出来

    所以预处理(f(n,2n+1))范围内的dp值 然后拉格朗日插值即可。

    #include<cstdio>
    #include<cstring>
    const int N = 1e3 + 7;
    typedef long long ll;
    inline ll fst(ll b, ll k, ll p) {
      ll ans = 1ll;
      while (k) {
        if (k & 1) ans = ans * b % p; b = b * b % p, k >>= 1;
      } return ans;
    }
    ll lagr (ll *qx, ll *qy, int up, ll x) {
      ll res = 0;
      for (int i = 1; i <= up; i++) {
        ll s1 = 1, s2 = 1;
        for (int j = 1; j <= up; j++) if (i != j) {
          s1 = (ll)(s1 * (x - qx[j]) % mo) % mo;
          s2 = (ll)(s2 * (qx[i] - qx[j]) % mo + mo) % mo; 
        } res = (res + (ll)(s1 * fst(s2, mo - 2, mo) % mo) * qy[i] % mo) % mo;
      } return (res % mo + mo) % mo;
    }
    ll f[N][N]; int n, m; ll A, mo, fac[N*2], xi[N*2];
    int main() {
      scanf ("%lld%d%lld", &A, &n, &mo);
      m = n + n + 1, fac[0] = fac[1] = 1;
      for (int i = 0; i <= m; i++) f[0][i] = 1;
      for (int i = 2; i <= m; i++) fac[i] = (fac[i - 1] * i) % mo;
      for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++)
        f[i][j] = (ll)((f[i - 1][j - 1] * j) % mo + f[i][j - 1]) % mo;
      for (int i = 0; i <= m; i++) xi[i] = i;
      printf ("%lld", (fac[n] * lagr(xi, f[n], m, A)) % mo);
    }
    
  • 相关阅读:
    程序员版孔乙己
    痛!痛!痛!我们的好兄弟Git,一路走好!
    谈谈中台架构之交易中台
    一个单例还能写出花来吗?
    为什么数据库字段要使用NOT NULL?
    阿里二面:什么是mmap?
    退税不完全操作指南,我这样操作省了2000块!
    开源组件编排引擎LiteFlow发布里程碑版本2.5.0
    开源框架TLog核心原理架构解析
    对乱糟糟的日志说再见
  • 原文地址:https://www.cnblogs.com/cjc030205/p/11638102.html
Copyright © 2011-2022 走看看