牛客寒假算法基础集训营4 Applese 涂颜色 (费马小定理)

链接:https://ac.nowcoder.com/acm/contest/330/E
来源:牛客网
 

在这个游戏中,有一个 n 行 m 列的方阵。现在它要为这个方阵涂上黑白两种颜色。规定左右相邻两格的颜色不能相同。请你帮它统计一下有多少种涂色的方法。由于答案很大,你需要将答案对 109+7109+7 取模。

输入描述:

仅一行两个正整数 n, m,表示方阵的大小。

输出描述:

输出一个正整数,表示方案数对 109+7109+7 取模。

示例1

输入

复制

1 1

输出

复制

2

示例2

输入

复制

2 2

输出

复制

4

备注:

1≤n,m≤

 

其实这个题看懂了很简单,只要你确定了第一列,那么剩下的就确定了,那么第一列怎么确定呢,一个格子可以选择两种颜色,

那么一列n个格子,就有2^{n}种情况

那么新的问题来了,题上可知N最大为10的1000000次,而longlong最多也就10的18次,那怎么求这超级无敌雷霆霹雳大的次幂呢?

费马小定理登场!

定理内容:假如p是质数,且gcd(a,p)=1(也就是a不为p的倍数),那么 a^(p-1)≡1(mod p)

由题可知,1e9+7是个质数,2是整数,a与p互质显而易见,所以现在我们的目的就是想办法把2^{n}(%(1e9+7)降幂为2^k%(1e9+7)

已知a^(p-1) = 1,且n可能很大很大,就看n里包括多少个p-1,把这些都丢掉求剩下的就好。假设有x个p-1(p=1e9+7)则:2^{n} = 2^{x*(p-1))}2^{k}1^{x} * 2^{k}2^{k} ,所以直接求2^k就好,k = (n)%(p-1)

由于n过于长,就用字符串存储,之后边转化为数边取余,最后结果quick_pow(2,ans)%mod即可。 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7; 
ll pow1(ll a,ll b)
{
    ll r=1;
    while(b)
    {
        if(b&1) r=r*a%mod;
        a=a*a%mod;
        b/=2;
    }
    return r;
}
int main()
{
   string a,b;
   cin>>a>>b;
   ll ans=0;
   int len=a.size();
   for(int i=0;i<len;i++)
    ans=(ans*10+a[i]-'0')%(mod-1);
   printf("%lld\n",pow1(2ll,ans));
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值