题意:给一个 行 列的方阵上色,只能上黑色或者白色,且必须满足左右相邻的格子颜色不能相同,问有多少种上色的方法。
思路:可以得出一行只有两种上色方法,而相邻两行之间互不影响,所以答案就是 。
解法一:
由于
范围过大,可以通过欧拉降幂来减小时间复杂度。
欧拉降幂:
由于
,所以
为质数,质数
的欧拉函数
为
。降幂后再通过快速幂即可求解。
#-*-coding:utf-8 -*-
n ,m = map(int ,input().split(" "))
p = 1000000007
n = n % (p - 1) + p - 1
a = [0]*12
b = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
len = -1
while n > 0:
len += 1
a[len] = n % 10
n = n // 10
ans = 1
for i in range(len):
ans = ans * b[a[len - i]] % p
ans = pow(ans ,10) % p
ans = ans * b[a[0]] % p
print(ans)
解法二:
因为是模数
是质数,所以也可以用费马小定理来进行降幂。
费马小定理:
(
为质数)
代码同解法一是一样的
解法三:
c++直接用十进制快速幂
十进制快速幂:
设
则
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
const long long p = 1e9 + 7;
string a, b;
int num[10] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512};
long long ans, x;
int main()
{
cin >> a >> b;
ans = 1;
int len = a.size() - 1;
for (int i = 0; i < len; ++i)
{
(ans *= num[a[i] - '0']) %= p;
x = ans;
for (int j = 2; j <= 10; ++j)
(ans *= x) %= p;
}
(ans *= num[a[len] - '0']) %= p;
printf("%lld\n", ans);
return 0;
}