hdu 1452 Happy 2004(数论:积性函数+快速幂+同余方程+扩展欧几里得算法)

本文介绍了数论中积性函数的概念及性质,并利用这些性质解决了一类与因子之和有关的问题。通过快速幂算法实现了高效计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这道题运用到积性函数

先介绍下积性函数及其性质:

在数论中的积性函数:对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时f(ab)=f(a)f(b),在数论上就称它为积性函数。若对于某积性函数 f(n) ,就算a, b不互质,也有f(ab)=f(a)f(b),则称它为完全积性

对于积性函数有如下性质:


而某个数的所有因子之和对应的函数恰为积性函数,这点记住就好,至于为什么感觉如果不是专业学这个的就不必要深究了,那么我们定义f(n)为n的所有因子之和,则对于该题f(2004) = f(2^2)*f(3)*f(167)//素数打下表可以得到

那么f(p1^a1)在p1为素数时等于什么呢?

很容易知道p1^a1的因子为1 p1 p1^2 ... p1^a1

所以其和为(p^(a1+1)-1)/(p-1)//等比序列求和

于是

f(2004^k)%29 = f(2^(2*k)) * f(3^k) * f(167^k)%29

=(2^(2*k+1)-1) * ((3^(k+1)-1)/2) * ((167^(k+1)-1)/166) % 29

根据同余方程:若a = b % m 则a^k = b^k % m

结合(a ± b) % m = a%m ± b%m

所以原式=(2^(2*k+1)-1) * ((3^(k+1)-1)/2) * ((22^(k+1)-1)/21) % 29

再结合公式:

(a*b) % m = a%m * b%m

(a/b) % m = (a * b^(-1))%m

b与b^(-1)关于m互逆,即b * b^(-1) %m = 1(b^(-1)为整数)

对应扩展欧几里得方程b*x = 1(mod m) 解出b即为b^-1

因为这里只需要求2和166的逆,直接找出即可,没有写扩展欧几里得的必要

很容易得到

2的逆元素是15,因为2*15=30 % 29=1 % 29
21的逆元素是18,因为21*18=378% 29 =1 % 29

所以计算下式即可:

a=(pow(2,2*x+1,29)-1)% 29;
b=(pow(3,x+1,29)-1)*15 % 29;
c=(pow(22,x+1,29)-1)*18 % 29;
ans=(a*b)% 29*c % 29;

再写一个快速幂即可!

代码如下:

#include <math.h>
#include <stdio.h>

int Pow(int a, int b, int c) {
    int ans = 1;
    while(b) {
        if(b & 1)
            ans = ans%c*(a%c)%c;
        a = a%c*a%c;
        b >>= 1;
    }
    return ans;
}

int main(void) {
    int n, c1, c2, c3;
    while(scanf("%d", &n), n) {
        c1 = Pow(2, 2*n+1, 29)-1;
        c2 = (Pow(3, n+1, 29)-1)*15%29;
        c3 = (Pow(22, n+1, 29)-1)*18%29;
        printf("%d\n", c1*c2%29*c3%29);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值