hdu 4704 (费马小定理 )

传送门

题意:  给你一个数n  你要找出他的最大 组成方案 就比如  3  那么一个数的时候 只有3  两个数的时候就有 1 2   和  2 1  两种

三个数的时候就有  1 1 1   一种  ,  那么找一下规律就是 n  的种类数就是2 的n-1  次方。

数论基础:  费马小定理。

a^(p-1) %p=1    注意  p  是素数!!!

费马小定理的公式 ,我们知道  1e9+7  是一个素数 ,既然n 可以非常的大 ,那么我们就需要将   2 的n-1  次方的

这个次方给降下来,  那么我们就可以用费马小定理。  既然 a^(p-1) %p=1  那么  2^(mod-1)%mod 肯定也等于

1  那么我们就可以将n-1  降到 mod  之内的数  ,方法当然就是  -1   然后  取模  mod-1  了。。  这样的话就

可以转化成   快速幂了。


代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int N =1e5+5;
const ll mod=1e9+7;

string s;
int num[N];

ll chuli()
{
    ll ans=0;

    for(int i=0;i<s.length();i++) num[i]=s[i]-'0';
    int len=s.length();

    for(int i=0;i<len;i++){
        ans*=10;  ans+=num[i];
        ans%=(mod-1);
    }

    //cout<<ans<<endl;

    ans-=1;
    ans=(ans+mod-1)%(mod-1);
    //cout<<ans<<endl;

    return ans;
}

ll quick_pow(ll a,ll k)
{
    ll ans=1;
    while(k)
    {
        if(k&1)
        {
            ans=(ans*a)%mod;
        }
        a=(a*a)%mod;
        k/=2;
    }
    return ans%mod;
}

int main()
{
    while(cin>>s)
    {
        ll k=chuli();

    ll ans=quick_pow(2,k);
    ans=(ans+mod)%mod;

    cout<<ans<<endl;

    }

    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值