The Galactic Olympics (第二类斯特林数)

d's'f's 

Altanie is a very large and strange coun蒟蒻JHYtry in Mars. People of Mars ages a lot. Some of them live for thousands of centuries!

Your old friend Foki "The president of the Martian United States of Altanie" is the oldest man on Mars. He's very old no one knows how old he is! Foki loves children, so, he had (0 < K ≤ 106) children!

The government in Altanie decided to send a team of athletes to Venus. To participate in (0 < N ≤ 103) different game in the Galactic Olympics. So Foki told them to send his children instead!

Foki is in a big problem. How can he decide whom of his children is going to participate in which game, at the same time his children must participate in all the games and every one of his children get to participate in at least one game?

Note that in a certain arrangement, each one of Foki's children can participate in multiple games in the Olympics, but each game must be arranged to exactly one player.

Your job is to help Foki and answer his question: in how many way can he arrange his children to the games in Venus Olympics while satisfying the previous two conditions.

Input

The first line of the input contains T the number of the test cases. Each test is represented with two integers on a single line. ( 0 < N ≤ 103 ) the number of the games in the Olympics, ( 0 < K ≤ 106 ) the number of Foki's children.

Output

For each test case print one line contains the answer to Foki's question. Since the answer is very large. Print the answer modulo 109 + 7

Example

Input

1
3 2

Output

滴答滴答---题目链接

题意:

  首先每个人至少要参加一个项目,并且一个项目最多只能属于一个人,所以我们可以很容易的建出模型: 有n个不同的物品,我们要把它们分别放入k个有序的集合,并且要求每个集合至少要有一个物品,求方案总数。
    我们知道,当集合无序的时候,方案数就是 S(n,k) ,即第二类斯特林数的第n行第k列的值; 集合有序的时候,再乘上 k! 就行了

如果K>n,就无解;

如果K==n,就答案是P(n,n);

如果K<n,答案就是s(n,K)*P(K,K);

P为排列数,s为第二类斯特林数。

第二类斯特林数就是将n个球,划分为K个非空集合的方案数(无序),所以要再乘上集合数的全排列。

#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
#define MOD 1000000007ll
int T,n,K;
ll f[1010][1010],jc[1000010];
int main()
{
    freopen("galactic.in","r",stdin);
    f[1][1]=1;
    for(int i=2; i<=1000; ++i)
        for(int j=1; j<=i; ++j)
            f[i][j]=(f[i-1][j-1]+(ll)j*f[i-1][j]%MOD)%MOD;
    jc[0]=1;
    for(int i=1; i<=1000000; ++i)
        jc[i]=jc[i-1]*(ll)i%MOD;
    scanf("%d",&T);
    for(; T; --T)
    {
        scanf("%d%d",&n,&K);
        if(n==K)
        {
            ll ans=1;
            for(int i=1; i<=K; ++i)
                ans=ans*(ll)i%MOD;
            printf("%d\n",(int)ans);
        }
        else if(n>K)
            printf("%d\n",(int)(f[n][K]*jc[K]%MOD));
        else
            puts("0");
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值