• bzoj4559&&dtoj#2672. 成绩比较 (mark)


    题目描述:

    THU 的 G 系中有许许多多的大牛,比如小 R 的室友 B 神。B 神已经厌倦了与其他的同学比较 GPA(Grade Point Average,平均学分绩),他只在意 G 系中共有多少同学被他“碾压”。

    B 神声称,在 G 系共有 $k$ 位同学被他碾压。同是 G 系大牛的 D 神则认为 B 神在吹牛,他查到了 B 神每门必修课在 G 系的排名。他用了 $173$ 毫秒的时间就计算出了有多少种情况使得 B 神所说的话成立。现在他想考考聪明的你,看你是否也能求出这个情况数。

    G 系共有 $n$ 位同学,$m$ 门必修课。这 $n$ 位同学的编号为 $0$ 到 $n - 1$ 的整数,其中 B 神的编号为 $0$ 号。这 $m$ 门必修课编号为 $0$ 到 $m - 1$ 的整数。如果在每门课上 A 获得的成绩均小于等于 B 获得的成绩,则称 A 被 B 碾压。在 B 神的说法中,G 系共有 $k$ 位同学被碾压(不包括他自己),而其他 $n - k - 1$ 名同学则没有被他碾压。

    D 神查到了 B 神每门必修课的排名。这里的排名是指,如果 B 神某门课的排名为 $r$,则表示有且仅有 $r - 1$ 位同学这门课的分数大于 B 神的分数,有且仅有 $n - r$ 位同学这门课的分数小于等于 B 神(不包括他自己)。

    我们需要求出全系所有同学每门必修课得分的情况数,使其既能满足 B 神的说法,也能符合 D 神查到的排名。这里两种情况不同当且仅当有任意一位同学在任意一门课上获得的分数不同。你不需要像 D 神那么厉害,你只需要计算出情况数模 $10^9 + 7$ 的余数就可以了。

    算法标签:DP,拉格朗日插值

    思路:

    暂时咕着

    以下代码:

    #include<bits/stdc++.h>
    #define il inline
    #define LL long long
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=105,p=1e9+7;
    int x[N],ll[N],rr[N];
    int f[N][N],n,m,st,h[N],rk[N],g[N],c[N][N],ny[N],op;
    il int read(){
        int x,f=1;char ch;
        _(!)ch=='-'?f=-1:f;x=ch^48;
        _()x=(x<<1)+(x<<3)+(ch^48);
        return f*x;
    }
    il int mu(int x,int y){
        if(x+y>=p)return x+y-p;
        return x+y;
    }
    il int ksm(LL a,int y){
        LL b=1;
        while(y){
            if(y&1)b=b*a%p;
            a=a*a%p;y>>=1;
        }
        return b;
    }
    il int lag(int u,int r){
        for(int i=1;i<=n+1;i++){
            x[i]=mu(x[i-1],1ll*ksm(i,n-r)*ksm(u-i,r-1)%p);
            if(i==u)return x[i];
        }
        ll[0]=rr[n+2]=1;
        int ans=0,res;
        for(int i=1;i<=n+1;i++)ll[i]=1ll*ll[i-1]*(u-i)%p;
        for(int i=n+1;i;i--)rr[i]=1ll*rr[i+1]*(u-i)%p;
        for(int i=1;i<=n+1;i++){
            res=1ll*ll[i-1]*rr[i+1]%p*x[i]%p*ny[n+1-i]%p*ny[i-1]%p;
            if((n+1-i)&1)ans=mu(ans,p-res);
            else ans=mu(ans,res);
        }
        return ans;
    }
    int main()
    {
        n=read();m=read();st=read();
        for(int i=1;i<=m;i++)h[i]=read();
        for(int i=1;i<=m;i++)rk[i]=read();
        ny[0]=ny[1]=1;
        for(int i=2;i<=n+1;i++)ny[i]=p-1ll*(p/i)*ny[p%i]%p;
        for(int i=1;i<=n+1;i++)ny[i]=1ll*ny[i-1]*ny[i]%p;
        for(int i=0;i<=n;i++){
            c[i][0]=1;
            for(int j=1;j<=n;j++)c[i][j]=mu(c[i-1][j-1],c[i-1][j]);
        }
        for(int i=1;i<=m;i++)g[i]=lag(h[i],rk[i]);
        f[0][n-1]=1;
        for(int i=1;i<=m;i++){
            for(int j=st;j<n;j++){
                for(int k=j;k<=min(n,j+rk[i]-1);k++){
                    f[i][j]=mu(f[i][j],f[i-1][k]*c[k][j]%p*c[n-k-1][n-j-rk[i]]%p);
                }
            }
        }
        int ans=f[m][st];
        for(int i=1;i<=m;i++)ans=1ll*ans*g[i]%p;
        printf("%d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    python函数续
    模拟数据库查询操作
    文件处理
    字符编码
    python函数
    ACM-ICPC 2018 南京赛区网络预赛Skr
    bzoj3676: [Apio2014]回文串 pam
    Wannafly挑战赛23B游戏
    bzoj4804: 欧拉心算 欧拉筛
    bzoj3884: 上帝与集合的正确用法 扩展欧拉定理
  • 原文地址:https://www.cnblogs.com/Jessie-/p/10488256.html
Copyright © 2020-2023  润新知