zoukankan      html  css  js  c++  java
  • 【TJOI2018】教科书般的亵渎

    题面

    题目描述

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

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

    输入输出格式

    输入格式:

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

    每组组测试数据第一行为(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\%)的数据,有(mleq1)

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

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

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

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

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

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

    题目分析

    模拟题,(可是我不会)

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

    第二类Stirling数

    [egin{split} sum_{i=0}^ni^k&=sum_{i=0}^nsum_{j=0}^kinom ijegin{Bmatrix}k\jend{Bmatrix}j!\ &=sum_{j=0}^kegin{Bmatrix}k\jend{Bmatrix}j!sum_{i=0}^ninom{i}{j}\ &=sum_{j=0}^kegin{Bmatrix}k\jend{Bmatrix}j!inom{n+1}{j+1} end{split} ]

    由于(kleq 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<<'
    ';
    	}
    	return 0;
    }
    
  • 相关阅读:
    笔记-归并排序
    Repeated Substring Pattern
    Assign Cookies
    Number of Boomerangs
    Paint Fence
    Path Sum III
    Valid Word Square
    Sum of Two Integers
    Find All Numbers Disappeared in an Array
    First Unique Character in a String
  • 原文地址:https://www.cnblogs.com/Emiya-wjk/p/10018606.html
Copyright © 2011-2022 走看看