NOIP 模拟题 小G的城堡

来源:互联网 发布:新游上线软件 编辑:程序博客网 时间:2024/04/29 19:45

文件名 输入文件 输出文件 时间限制 空间限制
castle.pas/c/cpp castle.in castle.out 1s 128MB

题目描述
小 G 家有一座城堡。城堡里面有 n 个房间,每个房间上都写着一个数字 p i 。小
G 拉着几个小伙伴在城堡里面玩耍, 他们约定, 如果某个人当前站在 i 房间里面, 下
一步这个人就会去 p i 房间,再下一步这个人去 p p i 。
为了增加趣味性,小 G 想重新书写每个房间的 p i ,以满足:
• 如果从编号 1 到 k 中的某个房间开始,按照规则走,必须能够走到 1 号房间。
特别地,如果从 1 号房间开始走,也要能够走回 1 号房间(至少走一步,如果
p 1 = 1,从 1 走到 1 也算合法) 。
• 如果从编号大于 k 的某个房间开始,按照规则走,一定不能走到 1 号房间。
小 G 想知道,有多少种书写 p i 的方案,可以满足要求。

输入格式
输入文件一行两个数字 n,k,含义如题。

输出格式
输出文件一个数字,表示合法的方案数。答案对 10^9 + 7 取模。

样例输入 1
5 2
样例输出 1
54
样例输入 2
7 4
4
样例输出 2
1728

数据范围
对于 40% 的数据,1 ≤ n ≤ 8
对于 70% 的数据,1 ≤ n ≤ 10 5
对于 100% 的数据,1 ≤ n ≤ 10 18 ,1 ≤ k ≤ min(8,n)。

考试的时候把模数打成了1e9+9,QAQ ,直接100->40。内心是很受伤害的。

手玩样例找规律是可以找出来的。

做法:
– n<=8
– 直接爆搜每个点的出边指向谁,然后检查即可。
– n<=10^5
– 我们发现,前k个点肯定和前k个点互相连边。
后n-k个点肯定不会连到前k个点里面去。
– 所以,我们只要爆搜前k个点连接的方案,然后
检查;后n-k个点,只要连的是后n-k个点,爱
怎么连怎么连,方案数是(n-k)^(n-k)。最后把
两部分方案数乘起来就行。
– n<=10^18
– 快速幂即可。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define LL long longusing namespace std;const int MOD=1000000007;LL n,k,ans;LL q_pow(LL x,LL p){    LL s=1;x=x%MOD;    while(p)    {        if(p&1) s=(s*x)%MOD;        x=(x*x)%MOD;        p>>=1;    }    return s;}int main(){    freopen("castle.in","r",stdin);    freopen("castle.out","w",stdout);    scanf("%lld%lld",&n,&k);    ans=(q_pow(k,k-1)*q_pow(n-k,n-k))%MOD;    printf("%lld",ans);    return 0;}