zoukankan      html  css  js  c++  java
  • [JLoi2016]成绩比较

    题解:

    一道不错的题目

    好像有容斥的方法。。我没看不知道

    首先dp是比较简单的

    f[i][j]表示考虑了前m门课,完全碾压了j个人

    那么转移是

    f[i][j]=sigma { f[i-1][k]*C(j,k)*C(n-j,a[i]-k) } *pi

    时间复杂度n^3

    其中pi表示选出他们分数的方案数

    我们显然可以通过枚举我的得分来确定pi

    pi=sigma {(maxn-x)^(rank[i]-1)*x^(n-rank[i])}

    再下面就是看了别人题解才知道得。。

    首先maxn非常大,所以暴力算一定是不可以的

    上面的式子看上去比较复杂

    将它写作 sigma{x,(k-x)^a*x^b}

    将(k-x)^a用二项式定理展开

    得到 C()*x^a*x^b+C()*k*x^a-1*x*b+.....

    将每项拆开

    得到C()*k^...*sigma{x,x^(a+b)}+......+......

    现在的问题就在于维护自然数幂和了

    由于模数是1e9+7

    选择拉格朗日插值就可以了

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define IL inline
    #define rint register int
    #define rep(i,h,t) for (rint i=h;i<=t;i++)
    #define dep(i,t,h) for (rint i=t;i>=h;i--)
    char ss[1<<24],*A=ss,*B=ss;
    IL char gc()
    {
      return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++; 
    }
    template<class T>IL void read(T &x)
    {
      rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
      while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48);  x*=f;
    }
    const int N=3e2+10;
    const int mo=1e9+7;
    const int INF=1e9;
    int a[N],b[N],r[N],C[205][205],dp[N][N],f[N],jc[N];
    int n,m,k;
    IL void js(int &x,int y)
    {
      x+=y;
      if (x>mo) x-=mo;
    }
    int qpow(int x,int y)
    {
      if (y==0) return(1);
      if (y==1) return(x);
      int kk=qpow(x,y/2);
      kk=(1ll*kk*kk)%mo;
      if (y%2) kk=(1ll*kk*x)%mo;
      return(kk);
    }
    int query(int x,int k)
    {
      rep(i,1,k+2) f[i]=(f[i-1]+qpow(i,k))%mo;
      if (x<=k+2) return(f[x]);
      jc[0]=1;
      rep(i,1,k+2) jc[i]=(1ll*jc[i-1]*i)%mo;
      int now=1,ans=0;
      rep(i,1,k+2) now=1ll*now*(x-i)%mo;
      rep(i,1,k+2)
      {
        int inv1=qpow(x-i,mo-2);
        int inv2=qpow(1ll*jc[i-1]*jc[k+2-i]%mo,mo-2);
        if ((k+2-i)%2) inv2=-inv2+mo;
        js(ans,1ll*inv1*inv2%mo*now%mo*f[i]%mo);
      }
      return(ans);
    }
    int main()
    {
      freopen("1.in","r",stdin);
      freopen("1.out","w",stdout);
      read(n); read(m); read(k);
      rep(i,1,m) read(a[i]);
      rep(i,1,m) read(r[i]),b[i]=n-r[i];
      rep(i,0,200) C[i][0]=1;
      rep(i,1,200)
        rep(j,1,i)
          C[i][j]=(C[i-1][j]+C[i-1][j-1])%mo;
      dp[1][b[1]]=C[n-1][b[1]];
      rep(i,2,m)
        rep(j,k,b[i])
        {
          int tmp=0;
          rep(kk,j,n-1)
          {
            int tmp1=dp[i-1][kk];
            js(tmp,1ll*tmp1*C[kk][j]%mo*C[n-kk-1][b[i]-j]%mo);
          }
          dp[i][j]=tmp;
        }
      int ans=dp[m][k];
      rep(i,1,m)
      {
        rint kk=0;
        rep(j,0,r[i]-1)
        {
          int kk1=1ll*C[r[i]-1][j]*query(a[i],j+n-r[i])%mo*qpow(a[i],r[i]-1-j)%mo;
          if (j%2) kk1=-kk1+mo;
          js(kk,kk1);
        }
        ans=(1ll*ans*kk)%mo;
      }
      cout<<(ans+mo)%mo<<endl;
      return 0; 
    }
  • 相关阅读:
    python基础-第十二篇-12.1jQuery基础与实例
    python基础-第十一篇-11.2DOM为文档操作
    [LC] 170. Two Sum III
    [Algo] 11. Rainbow Sort
    [LC] 31. Next Permutation
    [LC] 994. Rotting Oranges
    [LC] 863. All Nodes Distance K in Binary Tree
    [Algo] 132. Deep Copy Undirected Graph
    [LC] 138. Deep Copy Linked List With Random Pointer
    [Algo] 118. Array Deduplication IV
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9382015.html
Copyright © 2011-2022 走看看