牛客寒假算法基础集训营4 - E Applese 涂颜色 数论

题目链接

题意:给一个 n n m m 列的方阵上色,只能上黑色或者白色,且必须满足左右相邻的格子颜色不能相同,问有多少种上色的方法。

思路:可以得出一行只有两种上色方法,而相邻两行之间互不影响,所以答案就是 2 n 2^n

解法一:

由于 n n 范围过大,可以通过欧拉降幂来减小时间复杂度。
欧拉降幂: x n x n   m o d   φ ( m )   +   φ ( m )   ( m o d   m ) x^n≡x^{n \ mod \ \varphi(m) \ + \ \varphi(m)} \ (mod \ m)
由于 m = 1 0 9 + 7 m = 10^9+7 ,所以 m m 为质数,质数 m m 的欧拉函数 φ ( m ) \varphi(m) m 1 m-1 。降幂后再通过快速幂即可求解。

#-*-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)
解法二:

因为是模数 m m 是质数,所以也可以用费马小定理来进行降幂。
费马小定理: a p 1 1   ( m o d   p ) a^{p-1}≡1 \ (mod \ p) ( p p 为质数)
代码同解法一是一样的

解法三:

c++直接用十进制快速幂
十进制快速幂:
n = i = 0 d a i 1 0 i n=\sum_{i=0}^{d}a_i*10^i
m n = ( ( ( ( m a d ) 10 m a d 1 ) 10 m a d 2 ) 10 . . . ) 10 m a 0 m^n = ((((m^{a_d})^{10}*m^{a_{d-1}})^{10}*m^{a_{d-2}})^{10}...)^{10}*m^{a_0}

#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;
}

猜你喜欢

转载自blog.csdn.net/a302549450/article/details/86703418