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();
    }
    
  • 相关阅读:
    linux 短信收发
    sama5d3 环境检测 adc测试
    【Codeforces 723C】Polycarp at the Radio 贪心
    【Codeforces 723B】Text Document Analysis 模拟
    【USACO 2.2】Preface Numbering (找规律)
    【Codeforces 722C】Destroying Array (数据结构、set)
    【USACO 2.1】Hamming Codes
    【USACO 2.1】Healthy Holsteins
    【USACO 2.1】Sorting A Three-Valued Sequence
    【USACO 2.1】Ordered Fractions
  • 原文地址:https://www.cnblogs.com/cjc030205/p/11638085.html
Copyright © 2011-2022 走看看