[noip模拟]种花<快速幂+结论>
描述:
OI太可怕了,我决定回家种田。
我在后院里开辟了一块圆形的花圃,准备种花。种花是一种艺术,通过一定技术手法,花材的排列组合会让花变得更加的赏心悦目,这就是花艺。
当然你知道,我在种田之前是OIer,所以我不懂花艺,只会排列组合。我把花圃从圆心向外画线,分成了N块扇形,分别编号为1,2,3.....N,再从村里的商店采购了M种花。然后我大胆的决定:花圃中的每块只种M种花中的一种,相邻的两块不能种同一种花。我反应比较慢,所以我请来了机房里手速最快的强袭黯灭勋章鱼人守卫来帮我,让他试一下每种排列,看看哪种最令人赏心悦目。
有一些人,他们的美丽就在身边,也许就在自己身上,像艺术家一样,他们的眼光独到特别,可就因为他们不是艺术家,他们不被人们认可,被称之为另类。简单真实的事情总可以绽放最鲜艳的花,我欣赏这样的人的心理,当然拒绝粗鲁地对待一切。
正想着,他居然告诉我已经尝试完了。这怎么可能?这可一共有.......多少种方案来着?
众所周知的是,我的智商很低。
我想知道种花的方案一共有几种。
输入:
仅一行,包含两个整数,分别为N和M。
输出:
仅一行,包含一个整数,表示方案数。这个数可能很大,你只需要输出这个数对1000000007取模的结果。
样例输入:
3 3
样例输出:
6
数据范围:
对于20%的数据,0<N≤5,1<M≤5
对于60%的数据,0<N≤500,000
对于100%的数据,0<N≤10^18,1<M≤10^9
【思路】
其实这种一看就知道有结论或者有公式的题,最佳的做法就是先打出暴力程序,然后把暴力的结果用表格或者图像表示出来
然后你会惊奇的发现,你要的和你不要的东东都出现在图纸上了,然后你就可以愉快的开始推公式结论了
然后愉快的公式就跃然纸上。。。。
至于推这个公式,其实可以用数列推的,不过我没有那么做,我是先假设m=3,然后n在变换,推出公式,没错当m固定时,推出公式就明显是一道数学题了,接着对4进行推导,然后猜测m是未知数的情况并举例(时间不足才这样做,时间充足最好认真梳理并推导)
最后的结果就是(m-1)^n+(m-1)*(-1)^n;
到这里方法就很明显了,就是把n,m带进去,但是要注意一点,就是n是10^18次方这个范围,直接处理会爆掉,所以可以选择快速幂
快速幂的模板是
1 int pow(int x,int y){
2 int ans=1;
3 while(y){
4 if(y&1)ans*=x;
5 x*=x;y>>=1;
6 }
7 return ans;
8 }
然后这题就完了,直接输出即可,记得随时运算随时取模哦
1 #include<iostream>
2 #define mod 1000000007
3 using namespace std;
4 long long n,m,f;
5 long long pow(long long x,long long y){
6 long long ans=1;
7 while(y){
8 if(y&1)ans=((ans%mod)*(x%mod))%mod;
9 x=((x%mod)*(x%mod))%mod;
10 y>>=1;
11 }
12 return ans;
13 }
14 int main(){
15 cin>>n>>m;//(m-1)^n+(m-1)*(-1)^n
16 if(n==1){cout<<m;return 0;}
17 if(n&1)f=-1;else f=1;
18 long long ans=((f%mod)*((m-1)%mod))%mod;
19 long long sum=pow(m-1,n)%mod;
20 cout<<(ans+sum+mod)%mod;
21 }