HDU 6050 Funny Function【乘法逆元+快速幂】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6050

Funny Function

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1346 Accepted Submission(s): 686

Problem Description
Function Fx,ysatisfies:

For given integers N and M,calculate Fm,1 modulo 1e9+7.

Input
There is one integer T in the first line.
The next T lines,each line includes two integers N and M .
1<=T<=10000,1<=N,M<2^63.

Output
For each given N and M,print the answer in a single line.

Sample Input
2
2 2
3 3

Sample Output
2
33

Source
2017 Multi-University Training Contest - Team 2

首先推荐一篇比较好的博客:戳这里
这道题的数据量很大,如果一个个算的话数据量是很大的
我们可以试着找找规律:
n=2:1 2 6 18
n=3:1 5 33 229
n=4:1 10 150 2250
n=5:1 21 641 19861
从中可以看出:
当n是偶数时,从第二项开始后一项与前一项的比值都是固定的,且是2^n-1
当n是奇数时,从第二项开始后一项都是前一项固定倍数再减去一个固定值,这个固定值也是有规律可循的。
即(规律):
当n为偶数时,f[m]=f[m-1](2^n-1) (m>=3)即f[m]=f[2](2^n-1)^(m-2);
当n为奇数时,f[m]=f[m-1]*(2^n-1)-(2^1+…..+2^(n-2)) (m>=3);
当n=当 n=3..5..7..9 时,该常数为: 2..10..42..170;
2=2^1 10=2^1+2^3 42=2^1+2^3 +2^5 170=2^1+2^3 +2^5 +2^7

当然,规律找到这也不是最简的
最终规律:
这里写图片描述
不过从我能得到的规律到最终规律这几步没有推出来。
好多人都是用矩阵快速幂做的,我在开始推荐的博客里面两种方法都有。

注意:在对除数取余的时候为了防止精度的丢失,需要用到乘法的逆元,将除法变成乘法。这里使用的乘法逆元算法为费马小定理。

**费马小定理
在p是素数的情况下,对任意整数x都有x^p≡x(mod)p。
可以在p为素数的情况下求出一个数的逆元,x∗x^(p−2)≡1(mod p),x^(p−2)即为逆元。**
这个定理我也是第一次接触
乘法逆元讲解:http://blog.csdn.net/a27038/article/details/77017706
代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAX=1e5+10;
const int mod=1e9+7;
typedef long long LL;
LL km(LL a,LL b)
{//快速幂求a^b%mod;
    LL ans=1;
    while(b)
    {
        if(b&1)
            ans=(ans*a)%mod;
        b>>=1;
        a=(a*a)%mod;
    }
    return ans;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        LL n,m,ans;
        scanf("%lld%lld",&n,&m);
        LL k=(km(2,n)-1)%mod;
        LL k1=(km(k,m-1)*2)%mod;
        if(n%2!=0)
            k1++;
        ans=(k1 * km(3,mod - 2)) % mod;
        printf("%lld\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值