题面

题目描述

小豆喜欢玩游戏,现在他在玩一个游戏遇到这样的场面,每个怪的血量为\(a_i\),且每个怪物血量均不相同,小豆手里有无限张“亵渎”。亵渎的效果是对所有的怪造成11点伤害,如果有怪死亡,则再次施放该法术。我们认为血量为\(0\)怪物死亡。

小豆使用一张 “亵渎”会获得一定的分数,分数计算如下,在使用一张“亵渎”之后,每一个被亵渎造成伤害的怪会产生\(x^k\),其中\(x\)是造成伤害前怪的血量为\(x\)和需要杀死所有怪物所需的“亵渎”的张数\(k\)

输入输出格式

输入格式:

第一行输入一个\(T\)(\(T\leq10\)),表示有多少组测试数据

每组组测试数据第一行为\(n\)\(m\),表示有当前怪物最高的血量\(n\),和\(m\)种没有出现的血量

接下来行,每行\(1\)个数\(a_i\),表示场上没有血量为\(a_i\)的怪物

输出格式:

一共\(T\)行,每行一个数, 第ii行表示第ii组测试数据中小豆的最后可以获得的分数, 因为这个分数会很大需要模\(10^9+7\)

输入输出样例

输入样例:

2

10 1

5

4 2

1

2

输出样例:

415

135

说明

对于\(10\%\)的数据,有m=0

对于\(20\%\)的数据,有\(m\leq1\)

对于\(30\%\)的数据,有\(m\leq2\)

对于\(40\%\)的数据,有\(m\leq3\)

对于\(50\%\)的数据,有\(m\leq4\)

对于\(60\%\)的数据,有\(m\leq5\)

对于\(100\%\)的数据,有\(m\leq50\)

对于\(100\%\)的数据,有\(n\leq10^{13}\)

题目分析

模拟题,(可是我不会)

推法就不写了,只是写一下怎么使用Stirling数快速求出自然数幂和。

第二类Stirling数

\[\begin{split}
\sum_{i=0}^ni^k&=\sum_{i=0}^n\sum_{j=0}^k\binom ij\begin{Bmatrix}k\\j\end{Bmatrix}j!\\
&=\sum_{j=0}^k\begin{Bmatrix}k\\j\end{Bmatrix}j!\sum_{i=0}^n\binom{i}{j}\\
&=\sum_{j=0}^k\begin{Bmatrix}k\\j\end{Bmatrix}j!\binom{n+1}{j+1}
\end{split}
\]

由于\(k\leq 50\),可以直接暴力算现在的式子。

代码如下

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<iomanip>
#include<cstdlib>
#define MAXN 0x7fffffff
typedef long long LL;
const int N=55,mod=1e9+7;
using namespace std;
inline LL Getint(){register LL x=0,f=1;register char ch=getchar();while(!isdigit(ch)){if(ch==\'-\')f=-1;ch=getchar();}while(isdigit(ch)){x=x*10+ch-\'0\';ch=getchar();}return x*f;}
int ksm(int x,int k){
	int ret=1;x%=mod;
	while(k){
		if(k&1)ret=(LL)ret*x%mod;
		x=(LL)x*x%mod,k>>=1;
	}
	return ret;
}
int C(LL n,int m){
	if(n<m)return 0;
	int ret=1;
	for(LL i=n-m+1;i<=n;i++)ret=(LL)ret*(i%mod)%mod;
	for(int i=m;i;i--)ret=(LL)ret*ksm(i,mod-2)%mod;
	return ret;
}
int s[N][N],m;
LL n,a[N];
int Cal(LL k){
	int ret=0;
	for(int j=1,t=1;j<=m+1;j++,t=(LL)t*j%mod){
		ret=(ret+(LL)s[m+1][j]*t%mod*C(k+1,j+1)%mod)%mod;
	}
	return ret;
}
int main(){
	s[0][0]=1;
	for(int i=1;i<=51;i++){
		for(int j=1;j<=i;j++){
			s[i][j]=((LL)s[i-1][j]*j+s[i-1][j-1])%mod; 
		}
	}
	int T=Getint();
	while(T--){
		n=Getint(),m=Getint();
		for(int i=1;i<=m;i++)a[i]=Getint();
		sort(a+1,a+1+m);
		int ans=0;
		for(int i=0;i<=m;i++){
			ans=((LL)ans+Cal(n-a[i])-Cal(a[i]-a[i]))%mod;
			for(int j=i+1;j<=m;j++)
				ans=(ans-ksm(a[j]-a[i],m+1))%mod;
		}
		cout<<(ans+mod)%mod<<\'\n\';
	}
	return 0;
}

版权声明:本文为Emiya-wjk原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/Emiya-wjk/p/10018606.html