bzoj4559JLOI2016成绩比较

Posted AaronPolaris

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4559JLOI2016成绩比较相关的知识,希望对你有一定的参考价值。

4559: [JLoi2016]成绩比较

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 37  Solved: 29
[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



容斥原理+组合数,思路好

wangyuzee的题解很棒,orz

整体思路:先求出所有其他人和B神每门课分数相对大小的不同方案数,然后再计算每门课的方案数,两者乘积即为答案。


① 先算第一部分,直接算比较难,考虑容斥原理。

f[i]表示有i个人被碾压的方案数,则f[i]=C(n-1,i)*C(n-1-i,rnk[1]-1)*C(n-1-i,rnk[2]-1)*…*C(n-1-i,rnk[m]-1)-f[i+1]*C(i+1,i)-f[i+2]*C(i+2,i)-…-f[n-1]*C(n-1,i),即用至少i个人被碾压的方案数减去不合法的。f数组逆向递推即可求出。


② 再算第二部分,对于每一门分别计算,然后乘起来。

假设某一门课的总分为s,B神的名次和分数分别为rnk和x,则方案数为x^(n-rnk)*(s-x)^(rnk-1)。

展开化简得∑ C(rnk-1,i)*s^(rnk-1-i)*x^(n-rnk+i),0≤i≤rnk-1。

我们要对x=1,2,…,s的所有情况求和。

把x次数相同的项放在一起,转化成求1^p+2^p+...+s^p,p为常数。

设g[i]=1^i+2^i+...+s^i,然后观察规律:

(s+1)^(p+1)-s^(p+1)=C(p+1,0)*s^0+C(p+1,1)*s^1+…+C(p+1,p)*s^p

s^(p+1)-(s-1)^(p+1)=C(p+1,0)*(s-1)^0+C(p+1,1)*(s-1)^1+…+C(p+1,p)*(s-1)^p

……

2^(p+1)-1^(p+1)=C(p+1,0)*1^0+C(p+1,1)*1^1+…+C(p+1,p)*1^p

将式子相加,得:(s+1)^(p+1)-1=C(p+1,0)*g[0]+C(p+1,1)*g[1]+…+C(p+1,p)*g[p]

移项,得:g[p]=((s+1)^(p+1)-1-C(p+1,0)*g[0]-C(p+1,1)*g[1]-…-C(p+1,p-1)*g[p-1]) / C(p+1,p)

于是可以通过正向递推求出g数组。


这样,这个问题就完美解决了,时间复杂度O(n^3)。




#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define N 105
#define mod 1000000007
using namespace std;
int n,m,k;
ll ans,s[N],rnk[N],fac[N],inv[N],f[N],g[N];
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
inline ll getpow(ll x,ll y)
{
	ll ret=1;
	for(;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;
	return ret;
}
inline ll C(int x,int y)
{
	return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
int main()
{
	n=read();m=read();k=read();
	F(i,1,m) s[i]=read();
	F(i,1,m) rnk[i]=read();
	fac[0]=inv[0]=1;
	F(i,1,100) fac[i]=fac[i-1]*i%mod,inv[i]=getpow(fac[i],mod-2);
	D(i,n-1,k)
	{
		f[i]=C(n-1,i);
		F(j,1,m) f[i]=f[i]*C(n-1-i,rnk[j]-1)%mod;
		F(j,i+1,n-1) f[i]=(f[i]-f[j]*C(j,i)%mod+mod)%mod;
	}
	ans=1;
	F(i,1,m)
	{
		g[0]=s[i];
		F(j,1,n)
		{
			g[j]=(getpow(s[i]+1,j+1)-1+mod)%mod;
			F(l,0,j-1) g[j]=(g[j]-C(j+1,l)*g[l]%mod+mod)%mod;
			g[j]=g[j]*getpow(j+1,mod-2)%mod;
		}
		ll tmp=0,p=1;
		F(j,0,rnk[i]-1) tmp=(tmp+C(rnk[i]-1,j)*getpow(s[i],rnk[i]-1-j)%mod*g[n-rnk[i]+j]%mod*p+mod)%mod,p=-p;
		ans=ans*tmp%mod;
	}
	cout<<ans*f[k]%mod<<endl;
	return 0;
}


以上是关于bzoj4559JLOI2016成绩比较的主要内容,如果未能解决你的问题,请参考以下文章

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

●BZOJ 4559 [JLoi2016]成绩比较

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

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

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

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