有关数学的一些基础题

                                                                小M的因子和

                                       时间限制:1000 ms  |            内存限制:65535 KB

描述

小M在上课时有些得意忘形,老师想出道题目难住他。小M听说是求因子和,还是非常得意,但是看完题目是求A的B次方的因子和,有些手足无措了,你能解决这个问题吗?

输入
有多组测试样例
每行两个数 A ,B ,(1≤A,B≤10^9)
输出
输出A的B次方的因子和,并对9901取余。
样例输入
2 3
样例输出         15

 

 算法引入:

       

          为什么会有此个算法成立呢?在这里给出一个例子作为解释,如:

                        10 = 2^1 + 5^1,其因子和为(2^0 + 2^1)*(5^0 + 5^1)=(2^0*5^0) + (2^0*5^1) + (2^1*5^0) + (2^1*5^1) = 1 + 5 + 2 + 10;

题目解析:

         过与简单就此省略。

 

思路解析:

      我们知道没一个数都可以分解成由素数因子组成的数。so...你想到了没有。反正一开始我是没想到。就是把一个数分解成由有多个素数组成,且数可能有多个相同的素数组成。例如:8 = 2*2*2 = 2^3;10 = 2^1*5^1;so...现在你明白了没有,没有就算了。看来孩子你不适合数论。转行吧!!

所以经过上面的分析你懂的做了没有。还有就是,这题的N有点大,所以要用到分治思想和二分冪。

别的没什么好讲的,讲一下这题的分治思想吧。

a + a^2 + a^3 +.......+a^(n/2)+a^(n/2+1) + ......+ a^n = (a + a^2 + ......+a^(n/2)) + a^(n/2)*(a + a^2 + ....+a^(n/2))

 =  (a + a^2 +.....+ a^(n/2))*(1 + a^(n/2)) (n为奇数的时候,n为偶数的时候将会不同。自己思考为什么,或者看下面代码)

 

 

 
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;

typedef long long LL;
const int MOD = 9901;

LL PowMod(LL base,LL n)
{
	LL res = 1;
	base %= MOD;
	while(n)
	{
		if(n&1)
		  res = res*base%MOD;
        base = base*base%MOD;
		n >>= 1;
	}
	return res;
}
LL Sum(int base,int n)
{
	if(n == 0)
	  return 1;
	if(n&1) //odd
	   return(Sum(base,n/2)*(1+PowMod(base,n/2+1)))%MOD;
	else
	   return(Sum(base,n/2-1)*(1+PowMod(base,n/2+1))+PowMod(base,n/2))%MOD;
}
int main()
{
	int a,b;
	while(~scanf("%d%d",&a,&b))
	{
	    LL 	ans = 1;
	    int n = sqrt(a+0.5);
	    for(int i = 2;i <= n;++i)
	    {
	    	if(a%i==0){  //·Ö½âÖÊÒò×Ó
	    		int k = 0;
	    		while(a%i==0)
	    		{
	    			a /= i;
	    			++k;
	    		}
	    		ans = ans*Sum(i,k*b)%MOD;
	    	}
	    }
	    if(a > 1){
	    	ans = ans*Sum(a,b)%MOD;
	    }
	    printf("%d\n",int(ans));
	}
	return 0;
}
        


 

 

Geometric sum

时间限制: 1000  ms  |  内存限制: 65535  KB
难度: 3
描述
Compute (a + a^2 + … + a^n) mod m. (a+a2+an)mod
输入
Three integers a,n,m.
(1≤a,n,m≤10^18)
It ends with EOF.
输出
The only integer denotes the result.
样例输入
2 2 1000000000
样例输出
6 

 

 题意分析:

        就是要你求 (a + a^2 + … + a^n)Mod m的值。可以看出n,m都是出奇的大,直接算肯定超时,只能想出一个O(N)的复杂度。

思路分析:

       其实该题的考查的算法与上一题的是一样的,都是用到了分治思想。只是该题在处理的时候由于模太大了,所以要用到一个二进制的乘法取模的算法。既然是用到了新知识了,那就有必要介绍一下这个高级的东西。下面就给出二进制下的乘法取模模版吧

//base 为底数,n为次数,M为模
LL MulMode(LL base,LL n,LL M)
{
    LL res = 0;
    base %= M;
    while(n)
    {
        if(n&1){
          res += base;
          if(res > m) 
            res -= m;
        }
        base <<= 1;
        if(base > m)
          base -= m;
        n >>= 1;
    }
    return res;
}


 

然后该题的思路就与上面一题的思路就是相同的了,这里就不再赘述;

 

 
#include <stdio.h>

typedef long long LL;
LL m;

LL MulMod(LL base,LL n)
{
    LL res = 0;
    base %= m;
    while(n)
    {
        if(n&1){
          res += base;
          if(res > m) res -= m;
        }
        base <<= 1;
        if(base > m) base -= m;
        n >>= 1;
    }
    return res;
}
LL PowMod(LL base,LL n)
{
    LL res = 1;
    base %= m;
    while(n)
    {
        if(n&1)
           res = MulMod(res,base);
        base = MulMod(base,base);
        n >>= 1;
    }
    return res;
}

LL Solve(LL a,LL n)
{
    if(n == 1)
      return a%m;
    if(n&1)
      return (Solve(a,n-1)+PowMod(a,n))%m;
    LL tmp = Solve(a,n/2);
    return MulMod(tmp,PowMod(a,n/2)+1);
}
int main()
{
    LL a,n;
    while(scanf("%lld%lld%lld",&a,&n,&m)!=EOF)
    {
        printf("%lld\n",Solve(a,n));
    }
    return 0;
}
        


 

 

 

 

 

     

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值