感谢丁爷爷教我做这个题的后半部分。

首先,运用一发容斥原理,求出所有人与B神每门课分数相对关系的不同方案数。

这个似乎大(wo)家(lan)都(de)会(hui)了(yi),我就不说了,详见代码里的f。

然后,我们就需要计算每门课每个人的分数的方案数。对于每一门课,我们分别计算,然后把它们乘起来。

方便起见,令总分为s,名次为rk。

设B神的分数为x,则方案数为x^(n-rk)*(s-x)^(rk-1)

展开得到c(rk-1,0)*s^(rk-1)*x^(n-rk)-c(rk-1,1)*s^(rk-2)*x^(n-rk+1)+c(rk-1,2)*s^(rk-3)*x^(n-rk+2)-........

显然,我们需要对于x=1..s的所有情况求和。

我们把x次数相同的项放在一起,进行一波整理,问题就转化成了求1^k+2^k+...+s^k

我们设g(k)=1^k+2^k+...+s^k,我们列出一波式子然后观察:

(s+1)^k-s^k=c(k,1)*s^(k-1)     +c(k,2)*s^(k-2)     +...+c(k,k)*s^0

s^k-(s-1)^k=c(k,1)*(s-1)^(k-1)+c(k,2)*(s-1)^(k-2)+...+c(k,k)*(s-1)^0

............................................................................................................

2^k-1^k=c(k,1)*1^(k-1)     +c(k,2)*1^(k-2)     +...+c(k,k)*1^0

把这些式子全部相加,得到:

(s+1)^k-1=c(k,1)*g(k-1)+c(k,2)*g(k-2)+...+c(k,k)*g(0)

于是就可以通过递推的方式求出g

然后就做完了。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define ll long long
#define N 103
#define P 1000000007 using namespace std;
inline int read(){
int ret=0;char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while ('0'<=ch&&ch<='9'){
ret=ret*10-48+ch;
ch=getchar();
}
return ret;
} int fast_pow(int x,int y){
int ret=1;
while (y){
if (y&1) ret=(ll)ret*x%P;
x=(ll)x*x%P;
y=y>>1;
}
return ret;
} int bin[N];
int fact[N*100];
int inv[N*100];
int c(int n,int m){
return (ll)fact[n]*inv[m]%P*inv[n-m]%P;
} int f[N],g[N];
int person,subject,K;
int rank[N],s[N];
int main(){
for (int i=fact[0]=1;i<=1e3;++i) fact[i]=(ll)fact[i-1]*i%P;
for (int i=0;i<=1e3;++i) inv[i]=fast_pow(fact[i],P-2);
person=read();subject=read();K=read();
for (int i=1;i<=subject;++i) s[i]=read();
int maxrank=0;
for (int i=1;i<=subject;++i) maxrank=max(maxrank,rank[i]=read());
for (int i=person-maxrank;i>=K;--i){
f[i]=c(person-1,i);
for (int j=1;j<=subject;++j)
f[i]=(ll)f[i]*c(person-1-i,rank[j]-1)%P;
for (int j=person-maxrank;j>i;--j)
(f[i]+=P-(ll)f[j]*c(j,i)%P)%=P;
}
int res=1;
for (int i=1;i<=subject;++i){
g[0]=s[i];
bin[0]=1;
for (int j=1;j<=person;++j){
bin[j]=(ll)bin[j-1]*s[i]%P;
g[j]=fast_pow(s[i]+1,j+1)-1;
for (int k=1;k<=j;++k)
(g[j]+=P-(ll)c(j+1,k+1)*g[j-k]%P)%=P;
g[j]=(ll)g[j]*fast_pow(c(j+1,1),P-2)%P;
}
int now=0;
for (int j=0,k=1;j<rank[i];++j,k=-k)
(now+=((ll)k+P)*c(rank[i]-1,j)%P*g[person-rank[i]+j]%P*bin[rank[i]-j-1]%P)%=P;
res=(ll)res*now%P;
}
printf("%lld\n",(ll)res*f[K]%P);
return 0;
}

  

bzoj4559: [JLoi2016]成绩比较的更多相关文章

  1. bzoj4559[JLoi2016]成绩比较 容斥+拉格朗日插值法

    4559: [JLoi2016]成绩比较 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 261  Solved: 165[Submit][Status ...

  2. bzoj千题计划270:bzoj4559: [JLoi2016]成绩比较(拉格朗日插值)

    http://www.lydsy.com/JudgeOnline/problem.php?id=4559 f[i][j] 表示前i门课,有j个人没有被碾压的方案数 g[i] 表示第i门课,满足B神排名 ...

  3. BZOJ4559: [JLoi2016]成绩比较(dp 拉格朗日插值)

    题意 题目链接 Sol 想不到想不到.. 首先在不考虑每个人的真是成绩的情况下,设\(f[i][j]\)表示考虑了前\(i\)个人,有\(j\)个人被碾压的方案数 转移方程:\[f[i][j] = \ ...

  4. BZOJ4559 JLOI2016成绩比较(容斥原理+组合数学+斯特林数)

    容斥一发改为计算至少碾压k人的情况数量,这样对于每门课就可以分开考虑再相乘了.剩下的问题是给出某人的排名和分数的值域,求方案数.枚举出现了几种不同的分数,再枚举被给出的人的分数排第几,算一个类似斯特林 ...

  5. 【BZOJ4559】[JLoi2016]成绩比较 动态规划+容斥+组合数学

    [BZOJ4559][JLoi2016]成绩比较 Description G系共有n位同学,M门必修课.这N位同学的编号为0到N-1的整数,其中B神的编号为0号.这M门必修课编号为0到M-1的整数.一 ...

  6. 【BZOJ4559】成绩比较(动态规划,拉格朗日插值)

    [BZOJ4559]成绩比较(动态规划,拉格朗日插值) 题面 BZOJ 洛谷 题解 显然可以每门课顺次考虑, 设\(f[i][j]\)表示前\(i\)门课程\(zsy\)恰好碾压了\(j\)个\(yy ...

  7. 【bzoj4559】[JLoi2016]成绩比较(dp+拉格朗日插值)

    bzoj 题意: 有\(n\)位同学,\(m\)门课. 一位同学在第\(i\)门课上面获得的分数上限为\(u_i\). 定义同学\(A\)碾压同学\(B\)为每一课\(A\)同学的成绩都不低于\(B\ ...

  8. BZOJ4559&P3270[JLoi2016]成绩比较

    题目描述 \(G\)系共有\(n\)位同学,\(M\)门必修课.这\(N\)位同学的编号为\(0\)到\(N-1\)的整数,其中\(B\)神的编号为\(0\)号.这\(M\)门必修课编号为\(0\)到 ...

  9. 【bzoj4559】成绩比较

    Portal -->bzoj4559 补档计划 ​  借这题补个档--拉格朗日插值 ​​  插值的话大概就是有一个\(n-1\)次多项式\(A(x)\),你只知道它在\(n\)处的点值,分别是\ ...

随机推荐

  1. JavaScript Array和string的转换

    Array类可以如下定义: var aValues = new Array(); 如果预先知道数组的长度,可以用参数传递长度 var aValues = new Array(20); -------- ...

  2. [windows]win10家庭版切换到管理员账户

    背景:很多时候,在安装或者运行某些程序时会需要到管理员账户运行.而在win10家庭版却没有明显的位置可以让用户简单的进行切换.因此,有了以下的方法. 方法: 1.在搜索框中输入CMD,右键以管理员方式 ...

  3. 压缩Sqlite数据文件大小,解决数据删除后占用空间不变的问题

    最近有一网站使用Sqlite数据库作为数据临时性的缓存,对多片区进行划分 Sqlite数据库文件,每天大概新增近1万的数据量,起初效率有明显的提高,但历经一个多月后数据库文件从几K也上升到了近160M ...

  4. hive 内部表和外部表的区别和理解

    1. 内部表 create table test (name string , age string) location '/input/table_data'; 注:hive默认创建的是内部表 此时 ...

  5. C# Lambda表达式

    C# Lambda表达式 Lambda表达式 "Lambda表达式"是一个匿名函数,是一种高效的类似于函数式编程的表达式,Lambda简化了开发中需要编写的代码量.它可以包含表达式 ...

  6. java实现串口通讯

    一. 准备工作 1. 点击此下载java串口通讯相关工具 2. 将RXTXcomm.jar放到  %JAVA_HOME%\jre\lib\ext\  目录下,工程中引入该jar包 3. 将rxtxSe ...

  7. OOM killer

    Linux下有一种OOM KILLER 的机制,它会在系统内存耗尽的情况下,启用自己算法有选择性的kill 掉一些进程. 1. 为什么会有OOM killer 当我们使用应用时,需要申请内存,即进行m ...

  8. Javascript 中的严格模式

    原文:http://www.ruanyifeng.com/blog/2013/01/javascript_strict_mode.html 一.概述 除了正常运行模式,ECMAscript 5添加了第 ...

  9. linux下的一些操作(持续更新)

    文件操作 创建文件夹: mkdir 文件夹名称 查看当前目录的文件夹及文件:ls 参看当前文件夹下的所有文件及信息: ls -l 删除空文件夹:rmdir 文件夹名称 删除非空文件夹:rm rf 文件 ...

  10. 编译软件基础知识(2/2) via LinuxSir

    首先说下/etc/ld.so.conf: 这个文件记录了编译时使用的动态链接库的路径. 默认情况下,编译器只会使用/lib和/usr/lib这两个目录下的库文件 如果你安装了某些库,比如在安装gtk+ ...