zoukankan      html  css  js  c++  java
  • BZOJ 4559 成绩比较

    题意:https://www.lydsy.com/JudgeOnline/problem.php?id=4559

    Sol:

    第一眼看起来就是个稍微麻烦的组合数

    但是发现如果钦点哪些同学分数在某科目上分数比B神低以后的方案,就会出现没有被钦

    点碾压的同学也会被碾压,(后面钦点分数时可能钦点的一直是同一批人导致人数不够不被碾压的人数)

    于是可以考虑容斥,用至少(i)个人的方案算出恰好(k)个人的方案。

    可以得到

    因为被碾压的不能超过B君最大的一个排名,所以定义(up=min{n-R_i})

    [sum_{i=k}^{up}(-1)^{i-k}inom{i}{k}inom{n-1}{i}prod_{j=1}^minom{n-i-1}{R_j-1}sum_{x=1}^{U_j}(U_j-x)^{R_j-1}x^{n-R_j} ]

    发现后边枚举分数的(sum)实际上是在对关于(U_j)的多项式做前缀和,因此是个(n)次多项式,拉格朗日插值即可,因为x是自己取,所以可以做线性插值,复杂度(n^2)

    #include<cctype>
    #include<cmath>
    #include<cstdio>
    const int N = 1e2+9;
    typedef long long LL;
    const int upmax = 1e2+5;
    #define p 1000000007
    #define debug printf("GG
    ")
    inline int min(int a, int b) {return a > b ? b : a;}
    inline LL FST(LL b, LL k) {
      if (!b && k > 0) return 0;
      LL ans = 1LL;
      while (k) {
        if (k & 1) ans = ans * b % p; b = b * b % p, k >>= 1;
      } return ans;
    }
    int n, m, k, rk[N]; LL U[N];
    LL lagr(LL *ax, LL *ay, 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) continue;
          s1 = (LL)(s1 * ((x - ax[j]) % p + p) % p) % p;
          s2 = (LL)(s2 * ((ax[i] - ax[j]) % p + p)) % p;
        } res = (res + (LL)(s1 * FST(s2, p - 2)) % p * ay[i] % p) % p;
      } return res;
    } LL tx[N], ty[N], poly[N]; LL inv[N], fac[N];
    inline LL C(int n, int m) {
      return fac[n] * inv[n - m] % p * inv[m] % p;
    }int up;
    void init() {
      scanf("%d%d%d", &n, &m, &k);
      inv[1] = 1LL, fac[1] = 1LL, fac[0] = inv[0] = 1LL;
      for (int i = 2; i <= upmax; i++) inv[i] = inv[i - 1] * FST(i, p - 2) % p;
      for (int i = 2; i <= upmax; i++) fac[i] = fac[i - 1] * (LL)i % p;
      for (int i = 1; i <= m; i++) scanf("%lld", &U[i]);
      for (int i = 1; i <= m; i++) scanf("%d", &rk[i]);
      for (int i = 1; i <= m; i++) {
        int R = rk[i]; 
        for (int j = 1; j <= n + 1; j++) {
          tx[j] = j, ty[j] = 0;
          for (int x = 1; x <= j; x++) 
            ty[j] = (ty[j] + FST(j - x, R - 1) * FST(x, n - R) % p) % p;
        } poly[i] = lagr(tx, ty, n + 1, U[i]);
      }
      up = n;
      for (int i = 1; i <= m; i++) up = min(up, n - rk[i]);
    } 
    void solve() {
      LL ans = 0; 
      for (int i = k; i <= up; i++) {
        LL res = ((i - k) & 1 ? -1 : 1) * C(i, k) % p * C(n - 1, i) % p;
        for (int j = 1; j <= m; j++) 
          res = res * poly[j] % p * C(n - i - 1, rk[j] - 1) % p;
        ans = (ans + res) % p;
      } printf ("%lld
    ", (ans % p + p) % p);
    } 
    void debugR() {
      LL ans = 0;
      for (int i = k; i <= up; i++) {
        LL res = ((i - k) & 1 ? -1 : 1) * C(n - 1, i) % p * C(i, k) % p;
        res = (res % p + p) % p;
        for (int j = 1; j <= m; j++) {
          LL res2 = 0;
          for (int og = 1; og <= U[j]; og++) {
            res2 = (res2 + FST(U[j] - og, rk[j] - 1) * FST(og, n - rk[j]) % p) % p;
          }
          res = res2 * res % p * C(n - 1 - i, n - rk[j] - i) % p;
        } ans = (ans + res) % p;
      } printf("%lld
    ",(ans % p + p) % p);
    }
    int main() {
      init(), solve();
     // debugR();
    }
    
  • 相关阅读:
    版本控制 version control
    URL URI
    能用上的收藏
    函数式语言简介(functional language)
    h5触摸事件-判断上下滑动
    地理定位
    web存储
    jquerymobile tap事件被触发两次
    关于button的onclientclick事件和onclick事件
    .net 后台给html控件赋值
  • 原文地址:https://www.cnblogs.com/cjc030205/p/11638085.html
Copyright © 2011-2022 走看看