Happy 2004(积性函数、快速幂取模、费马小定理、求因数和)

题目

Consider a positive integer X,and let S be the sum of all positive integer divisors of 2004X. Your job is to determine S modulo 29 (the rest of the division of S by 29).

Take X = 1 for an example. The positive integer divisors of 20041 are 1, 2, 3, 4, 6, 12, 167, 334, 501, 668, 1002 and 2004. Therefore S = 4704 and S modulo 29 is equal to 6.
Input
The input consists of several test cases. Each test case contains a line with the integer X (1 <= X <= 10000000).
A test case of X = 0 indicates the end of input, and should not be processed.
Output
For each test case, in a separate line, please output the result of S modulo 29.
Sample Input
1
10000
0
Sample Output
6
10

积性函数

本题中,2004的约数和 S ( 200 4 x ) S(2004^x) 就是一个积性函数
积性函数:
p = a × b S ( p ) = S ( a ) × S ( b ) p = a \times b\Rightarrow S(p) = S(a) \times S(b)
p n = a n × b n S ( p n ) = S ( a n ) × S ( b n ) p^n = a^n\times b^n\Rightarrow S(p^n) = S(a^n) \times S(b^n)
a和b均为质数

求因数和

S ( p n ) = S(p^n) = p n + 1 1 p 1 {p^{n + 1} - 1}\over{p - 1}
p p 是质数

费马小定理

定理

假如是一个整数 a a
p p 是一个质数, a p a a^p - a 那么是 p p 的倍数,可以表示为
a p % p = a a^p \% p = a
如果 a a 不是 p p 的倍数,这个定理也可以写成
a p 1 % p = 1 a^{p - 1}\%p = 1
在本题中,费马小定理的应用为:
a a p p 互质时,
a p 1 % p = 1 a^{p - 1} \% p =1
再由同余定理: 1 % p = 1 1\%p = 1
可得 a p 1 % p = 1 % p = 1 a^{p-1}\%p = 1\%p = 1

取模

加减法

( a ± b ) % p = a % p ± b % p (a \pm b)\%p = a\%p \pm b\%p

乘法

( a × b ) % p = ( a % p ) × ( b % p ) % p (a \times b) \% p = (a\%p) \times (b \% p) \%p

除法

//不能直接分配了,要转化成乘法再做

结论

( a b ) % c = ( a × b c 2 ) % c (\frac{a}{b})\% c = (a \times b^{c - 2}) \% c

推导

( a b ) % c = ( a × b 1 ) % c = ( a × b 1 × 1 ) % c (\frac{a}{b})\% c = (a \times b^{-1}) \% c = (a \times b^{-1} \times 1 ) \%c
( a × b 1 × b c 1 ) % c = ( a × b c 2 ) % c (a \times b^{-1} \times b^{c - 1}) \% c = (a \times b^{c - 2}) \% c

快速幂取模

快速幂

x n x^n

int pow(int x,int n)
{
    int ans = 1,base = x;
    while(n)
    {
        if(n & 1)
            ans *= base;
        base *= base;
        n >>= 1;
    }
    return ans;
}

快速幂取模

x n % p x^n\%p

int pow_mod(int x, int n, int p)
{
    int base = x, ans = 1;
    while(n)
    {
        if(n & 1) ans *=  base;
        base = (base * base) % p;
        n >>= 1;
    }
    return ans % p;
}

题目代码

#include <stdio.h>
long long int pow_mod(int x,int b);
int cal(int x);
int main()
{
    int x[100],s[100];
    int counter = 0,i;
    scanf("%d",x);
    while(x[counter] != 0)
    {
        s[counter] = cal(x[counter]) % 29;
        //printf("%d\n",s[counter]);
        counter++;
        scanf("%d",&x[counter]);
    }
    for(i = 0;i < counter;i++)
        printf("%d\n",s[i]);
    return 0;
}
int cal(int x)
{
    int a,b,c;
    a = (pow_mod(2, 2 * x + 1) - 1 ) % 29;
    b = (pow_mod(3, x + 1) - 1) * pow_mod(2, 27) % 29;
    c = (pow_mod(22, x + 1) - 1) * pow_mod(21, 27) % 29;
    return a * b * c % 29;
}
long long int pow_mod(int x,int b)
{
    long long int base = x, ans = 1;
    while(b)
    {
        if(b & 1) ans *=  base;
        base = (base * base) % 29;
        b >>= 1;
    }
    return ans % 29;
}

坑点

1.取模那里要用long long int,用int 可能会不够长,我用int的时候会出现WA,改成long long int 就accepted了(不过我没想明白为什么不够长,base是不断取模的,按道理来讲,也不会太大啊?)

  • 我也不知道这道题happy不happy,反正我是不怎么happy了。。。
    总结了多位大佬们的博客,加上自己的一些理解,写了一份给自己看的总结,看不懂就去看看大佬们写的博客吧。这个博客主要还是写给我自己看的,阅读性不太强。
发布了39 篇原创文章 · 获赞 4 · 访问量 5763

猜你喜欢

转载自blog.csdn.net/weixin_45725137/article/details/104871484