简单数学题(杭电)
已知

求 F(n) mod 1000000007

这一道题让我很绝望,刚开始感觉是简单模拟,一看数据是1e18我就知道不会这么简单
正解:本题要用到取模运算和快速幂,以及还要用用数学知识进行约分
数学化简是最难的:

其中-sun是用sum-2sum得到的
1*2^0+2*2^1+3*2^2......
0+1*2^1+2*2^2......
错位相减(自己模拟一下)
代码如下:
#include<stdio.h>
#include<string.h>
typedef long long LL;
//LL q_mul(LL a, LL b, LL p) //快速乘法取模      这是为了防止在两个数做乘法运算的时候爆掉long long感觉和快速幂的原理差不多//
//例如32*5=32*(0101)=32*1*1+32*2*0+32*4*1+32*8*0;就是利用这个原理,是不是感觉和快速幂差不多
//{
//    LL ans = 0;
//    while (b)
//    {
//        if(b&1LL) ans=(ans+a)%p;
//        //or ans=(ans+(b%2*a)%p)%p;
//        a = (a +a) % p;
//        b >>= 1;
//    }
//    return ans;
//}
long long pow(long long x,long long y)//大家都知道(快速幂)
{
    if(!y) return 1;
    else
    {
        long long ans=1;
        while(y)
        {
            if(y&1LL)
            {
//            ans=q_mul(ans,x,1000000007);
//
                ans=((ans%1000000007)*(x%1000000007))%1000000007;
              //  printf("%lld\n",ans);
            }
            x=((x%1000000007)*(x%1000000007))%1000000007;//之前我没有在这里对x取余,导致x一直爆掉,下一次要记住了
            y>>=1;
        }
      //  printf("%lld\n",ans);
        return ans;
    }
}
int main()
{
    long long a,g;
    while(~scanf("%lld",&a))
    {
      //  g=q_mul((a-1),pow(2,a),1000000007);
        g=(((a-1)%1000000007*(pow(2,a)%1000000007))%1000000007+1)%1000000007;
        printf("%lld\n",g);
    }
    return 0;
}
其中还有一个知识就是:(a-b)%mod=(a%mod-b%mod)%mod=(a-b+mod)%mod;
这是为了防止a-b为负数

                
            
        
浙公网安备 33010602011771号