zoukankan      html  css  js  c++  java
  • 51nod A 魔法部落(逆元费马小定理)

    A 魔法部落

    小Biu所在的部落是一个魔法部落,部落中一共有n+1个人,小Biu是魔法部落中最菜的,所以他的魔力值为1,魔法部落中n个人的魔法值都不相同,第一个人的魔法值是小Biu的3倍,第二个人的魔法值是第一个人的3倍,以此类推。

    现在小Biu想知道整个部落的魔法值和是多少?由于答案比较大,请把答案对1e9+7取模之后输出。

     

    输入

    输入一个数N(0 <= N <= 10^9)

    输出

    输出:整个部落的魔法值和模1e9+7。

    数据范围

    对于20%的数据,n<=100;
    对于40%的数据,n<=1000000;
    对于100%的数据,n<=1000000000;

    输入样例

    3

    输出样例

    40

    样例解释

    3^0+3^1+3^2+3^3 = 1+3+9+27 = 40

      题意如此,此为等比数列,根据等比求和公式,为(3^(n+1)-1)/2  mod1e9+7

      由于n很大,做除数再取模会损失精度,所以我们需要把他转化为乘法来计算。那么就用到了逆元思想。

      逆元:方程 axequiv 1(mod\, : p) 的解称为 a 关于模 p 的逆,意思也为:ax%p==1。当 gcd(a,p)=1(即 ap 互质)时,方程有唯一解,否则无解。

          x为a关于p的逆元。

        我们把式子写成(a/b)%m,推理过程如下,字迹潦草,勿怪

      即我们需要求(a*c)mod  m。c为b的逆元。

      费马小定理:当 p 为质数时,有 a^{p-1}equiv 1(mod:\,p),那么易得出 a*a^{p-2}equiv 1(mod:\,p)

      根据题意,mod=1e9+7,即为p的位置,mod为质数,适用于费马小定理求逆元,c的位置即为b^(p-2)的位置,这样根据b求c就可以了。。b=2,则求2^(mod-2),利用快速幂来求

      

      上代码:

    #include<iostream>
    using namespace std;
    typedef long long ll;
    const int mod=1e9+7;
    int qk(ll a, ll b)
    {
        ll ans=1;
        a=a%mod;
        while(b)
        {
            if(b%2==1)
                ans=(ans*a)%mod;
            b=b/2;
            a=(a*a)%mod;
        }
        return  ans;
    }
    int main(){
        ll n;
        while(cin>>n)
        {
            ll c=qk(2,mod-2);
            ll zi=qk(3,n+1)-1;
            cout<<(zi%mod*c)%mod<<endl;
        }
    }

    一个队友给的优化,直接快速幂 ,模的时候mod*2即可,排除了结果为5e8的情况,那样会出现精度丢失...

  • 相关阅读:
    (Java实现) 洛谷 P1106 删数问题
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
    (Java实现) 洛谷 P1553 数字反转(升级版)
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1106 删数问题
    目测ZIP的压缩率
  • 原文地址:https://www.cnblogs.com/liyexin/p/11745656.html
Copyright © 2011-2022 走看看