bzoj4559: [JLoi2016]成绩比较

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

首先,运用一发容斥原理,求出所有人与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;
}

  

时间: 2024-10-24 19:46:47

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

bzoj千题计划270:bzoj4559: [JLoi2016]成绩比较

http://www.lydsy.com/JudgeOnline/problem.php?id=4559 f[i][j] 表示前i门课,有j个人没有被碾压的方案数 g[i] 表示第i门课,满足B神排名的分数安排方案数 g[i]的求法: 枚举B神这门课x分,则有n-Ri个人的分数<=x ,Ri-1个人的分数>x Ui 上限是1e9,但是g[i] 是一个关于Ui 的n次多项式,所以可以用拉格朗日插值法来求 递推 f[i][j]: 假设f[i-1][w] 转移到了f[i][j],j>=w 前i

bzoj4559 [JLOI2016]成绩比较 拉格朗日插值

题目描述 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位

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

[BZOJ4559][JLoi2016]成绩比较 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,则表示有且

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

4559: [JLoi2016]成绩比较 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 261  Solved: 165[Submit][Status][Discuss] Description G系共有n位同学,M门必修课.这N位同学的编号为0到N-1的整数,其中B神的编号为0号.这M门必修课编号为0到M- 1的整数.一位同学在必修课上可以获得的分数是1到Ui中的一个整数.如果在每门课上A获得的成绩均小于等于B获 得的成绩,则称A被B碾压.在B

bzoj 4559 [JLoi2016]成绩比较 —— DP+拉格朗日插值

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4559 看了看拉格朗日插值:http://www.cnblogs.com/ECJTUACM-873284962/p/6833391.html https://blog.csdn.net/lvzelong2014/article/details/79159346 https://blog.csdn.net/qq_35649707/article/details/78018944 还只会最简单的

【LuoguP3270】[JLOI2016] 成绩比较

题目链接 题目描述 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神的分数,有且仅

[JLOI2016] 成绩比较

推石子 首先设\(d[i]=\sum_{t=1}^{U[i]}t^{n-R[i]}(U[i]-t)^{R[i]-1}\),即第\(i\)门课程分数的合法分布方案数: 然后设\(f[i,j]\)表示前\(i\)门课程中\(j\)个人被碾压的合法方案数,转移有: \[ \begin{aligned} &f[i,j]=d[i]\times\sum_{k=1}^n\pmatrix{k\\k-j}\pmatrix{n-k-1\\(R[i]-1)-(k-j)}f[i-1,k] &f[0,n-1]=1

●BZOJ 4559 [JLoi2016]成绩比较

题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4559 题解: 计数dp,拉格朗日插值法.真的是神题啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊. 先来看看 dp定义:(由于每门课程的分数分布方案是独立的,所以先不管每科实际分数大小所贡献的方案数.)dp[i][j]:表示前 i门课程,只考虑分数相对大小关系时,B神碾压了 j个人的方法数也就是说上面的dp定义只是表示一个相对关系的方案数(即不考虑实际分数大小). 那么d

【BZOJ】4559: [JLoi2016]成绩比较 计数DP+排列组合+拉格朗日插值

[题意]n位同学(其中一位是B神),m门必修课,每门必修课的分数是[1,Ui].B神碾压了k位同学(所有课分数<=B神),且第x门课有rx-1位同学的分数高于B神,求满足条件的分数情况数.当有一位同学的一门必修课分数不同时视为两种情况不同.n,m<=100,Ui<=10^9. [算法]计数DP+排列组合+拉格朗日插值 [题解]把分数作为状态不现实,只能逐门课考虑. 设$f[i][j]$表示前i门课,有j个同学被碾压的情况数,则有: $$f[i][j]=g(i)\cdot\sum_{k=j