整数的因子和 ---TOJ 1089 Happy 2004

题意

题目链接:1089. Happy 2004
这个题目就是求出 2004Xmod29 的结果,其中 1X10000000

Input
1
10000
0

Output
6
10

思路

明显暴力解法肯定会超时, 数论问题首先要从整数的标准分解入手:

N=ki=1paii 其中 pi 是N 的质因子, ai 为其次数。

例如: 12=223
有了标准分解, 接着考虑 一个整数的是怎么构成因数的,就是由 质因子及其幂 相互相乘得到的,具体来说就是 我们每次可以取出 pi 的不同次数,来构成因数,这样就有 0,1,ai ,共有( ai +1) 种选择。 接着就是一个组合过程,看下面的式子:

ki=1(p0i+p1i++paii)

这个式子展开之后就是 所有的因子相加了 ,正是我们所求的~

下面就是求解这个式子结果了, 取模的话就直接分配进去按照二分幂 取摸,
不过这里有个技巧:

l Al+xmod m=Axmod m 其中 l[0,m] 成立,

只需要求出循环节 l 即可, 最后加上余下的那部分数字即可。2004的质因子为2,3,167
2的幂关于29的循环节是28;
3的幂关于29的循环节是28;
167的幂关于29的循环节是21;
2,3,167的循环节内的和 mod 29 正好为0;
因此只需要求出 循环节剩下的部分即可~

代码

#include <iostream>
#include <math.h>
#include <stdlib.h>
using namespace std;
int n;
int main()
{
    while(cin>>n&&n)
    {
        long long a=0,b=0,c=0,t=1;
        for(int i=0; i<(2*n+1)%28;i++)
            a+=(long long)(pow(2.0,i))%29;

        for(int i=0;i<(n+1)%28;i++)
            b+=(long long)(pow(3.0,i))%29;

        for(int i=0;i<(n+1)%14;i++){// 这里没有直接使用pow 函数,考虑到pow(167,20) 会超范围
            c+=t;
            t*=167;
            t%=29;
        }
        cout<<((a%29)*(b%29)*(c%29))%29<<endl;
    }
}

你可能感兴趣的:(TOJ)