4559: [JLoi2016]成绩比较

来源:互联网 发布:草图大师有mac版吗 编辑:程序博客网 时间:2024/05/16 12:52

4559: [JLoi2016]成绩比较

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 153  Solved: 100
[Submit][Status][Discuss]

Description

G系共有n位同学,M门必修课。这N位同学的编号为0到N-1的整数,其中B神的编号为0号。这M门必修课编号为0到M-
1的整数。一位同学在必修课上可以获得的分数是1到Ui中的一个整数。如果在每门课上A获得的成绩均小于等于B获
得的成绩,则称A被B碾压。在B神的说法中,G系共有K位同学被他碾压(不包括他自己),而其他N-K-1位同学则没
有被他碾压。D神查到了B神每门必修课的排名。这里的排名是指:如果B神某门课的排名为R,则表示有且仅有R-1
位同学这门课的分数大于B神的分数,有且仅有N-R位同学这门课的分数小于等于B神(不包括他自己)。我们需要
求出全系所有同学每门必修课得分的情况数,使其既能满足B神的说法,也能符合D神查到的排名。这里两种情况不
同当且仅当有任意一位同学在任意一门课上获得的分数不同。你不需要像D神那么厉害,你只需要计算出情况数模1
0^9+7的余数就可以了。

Input

第一行包含三个正整数N,M,K,分别表示G系的同学数量(包括B神),必修课的数量和被B神碾压的同学数量。第二
行包含M个正整数,依次表示每门课的最高分Ui。第三行包含M个正整数,依次表示B神在每门课上的排名Ri。保证1
≤Ri≤N。数据保证至少有1种情况使得B神说的话成立。N<=100,M<=100,Ui<=10^9

Output

 仅一行一个正整数,表示满足条件的情况数模10^9+7的余数。

Sample Input

3 2 1
2 2
1 2

Sample Output

10

HINT

Source

[Submit][Status][Discuss]



#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<algorithm>#include<cmath>#include<stack>using namespace std; const int N = 105;typedef long long LL;const LL mo = 1000000007; int n,m,k,Max[N],Rank[N],C[N][N],f[N][N],g[N]; inline int Mul(const LL &x,const LL &y) {return x * y % mo;}inline int Add(const int &x,const int &y) {return x + y < mo ? x + y : x + y - mo;}inline int Dec(const int &x,const int &y) {return x - y >= 0 ? x - y : x - y + mo;} inline int ksm(int x,int y){    int ret = 1;    for (; y; y >>= 1)    {        if (y & 1) ret = Mul(ret,x);        x = Mul(x,x);    }    return ret;} inline int Calc(int U,int R){    memset(g,0,sizeof(g));    for (int i = 1; i < N; i++)        for (int j = 1; j <= i; j++)            g[i] = Add(g[i],Mul(ksm(j,n - R),ksm(i - j,R - 1)));    int ret = 0;    for (int i = 1; i < N; i++)    {        int A = g[i],B = 1;        for (int j = 1; j < N; j++)        {            if (i == j) continue;            A = Mul(A,Dec(U,j)); B = Mul(B,Dec(i,j));        }        ret = Add(ret,Mul(A,ksm(B,mo - 2)));    }    return ret;} int main(){    #ifdef DMC        freopen("DMC.txt","r",stdin);    #endif         cin >> n >> m >> k; C[0][0] = f[0][n - 1] = 1;    for (int i = 1; i <= n; i++)    {        C[i][0] = 1;        for (int j = 1; j <= i; j++)            C[i][j] = Add(C[i - 1][j],C[i - 1][j - 1]);    }    for (int i = 1; i <= m; i++) scanf("%d",&Max[i]);    for (int i = 1; i <= m; i++) scanf("%d",&Rank[i]);    for (int i = 1; i <= m; i++)    {        int h = Calc(Max[i],Rank[i]);        for (int j = k; j <= n - 1; j++)            for (int t = j; t <= n - 1; t++)            {                if (t - j > Rank[i] - 1) break;                int now = Mul(C[t][t - j],C[n - 1 - t][Rank[i] - 1 - t + j]);                f[i][j] = Add(f[i][j],Mul(now,Mul(f[i - 1][t],h)));            }    }    cout << f[m][k] << endl;    return 0;}


0 0
原创粉丝点击