hdu1452 因子和的积性函数

对于一个大于1正整数n可以分解质因数:n=p0^a0*p1^a1*p2^a2*p3^a3*…*pk^ak,
则由约数个数定理可知n的正约数有(a0+1)*(a₁+1)(a₂+1)(a₃+1)…(ak+1)个,
那么n的(a0+1)(a₁+1)(a₂+1)(a₃+1)…(ak+1)个正约数的和为
s(n)= (p0^0+p0^1+p0^2+…p0^a0)(p1^0+p1^1+p1^2+…p1^a1)(p2^0+p2^1+p2^2+…p2^a2)…(pk^0+pk^1+pk^2+…pk^ak)

约数和公式证明:

pk^ak 的约数为:1 , pk , pk^2 , pk^3 , ... ,pk^ak

实际上n的约数是在p0^a0、p1^a1、p2^a2、...、pk^ak每一个的约数中分别挑一个相乘得来

所以它们的和为 :

 s(n)=(p0^0+p0^1+p0^2+…p0^a0)(p1^0+p1^1+p1^2+…p1^a1)(p2^0+p2^1+p2^2+…p2^a2)…(pk^0+pk^1+pk^2+…pk^ak)


容易理解,若gcd(a,b)=1 ,则 s(a*b) = s(a) * s(b)

看: hdu1452 Happy 2004

计算因子和 s(2004^X) mod 29 ,

2004=2^2 *3 *167

2004^X=2^2X * 3^X *167^X

s(2004^X) ) = s(2^2X) * s(3^X) * s(167^X)

  = (2^0+2^1+2^2+...+2^2x) * (3^0+3^1+3^2+...+3^x) * (167^0+167^1+167^2+...+167^x) 

  =  (2^0+2^1+2^2+...+2^2x) * (3^0+3^1+3^2+...+3^x) * (22^0+22^1+22^2+...+22^x) ................. 有(167%29=22)

  = (2^(2X+1)-1)  *  ((3^(X+1)-1)/2)  *  ((22^(X+1)-1)/21)

怎么算(a/b)%p ? 设 (a/b)%p = y;

a/b = k*p + y ;

a = k*p*b + y*b ;

因为p>y,则p*b > y*b

所以 y*b = a % (p*b) 

所以 (a/b)%p = y = a%(p*b) / b 

#include<cstdio>
#include<cmath>
using namespace std;
int quick(int a,int b,int m){     //a^b%m
    int ans = 1,tmp = a;   
    while(b){
        if(b&1) {
            ans*=tmp;
            ans%=m;
        }
        tmp*=tmp; //低级错误,这里不应该是tmp*=a
        tmp%=m;
        b>>=1;
    }
    return ans;
}
int main(){
    int x,a1,a2,a3;
    while(scanf("%d",&x)!=EOF&&x){
        a1 = quick(2,2*x+1,29)-1;
        if(a1<0) a1+=29;

        a2 = quick(3,x+1,2*29)-1;
        if(a2<0) a2+=2*29;
        a2/=2;

        a3 = quick(22,x+1,21*29)-1;
        if(a3<0) a3+=21*29;
        a3/=21;
        printf("%d\n",a1*a2*a3%29);
    }
}


计算(a/b)%p的另一种方法:(转载自网络)

%运算法则 1. (a*b) %p= ( a%p) *(b%p)

%运算法则 2. (a/b) %p= ( a *b^(-1)%p) 除法的

s(2004^X)=2^(2X+1)-1* (3^(X+1)-1)/2  *(22^(X+1)-1)/21

(a*b)/c %M= a%M* b%M  * inv(c)

c*inv(c)=1 %M    模为1的所有数  invc)为最小可以被c整除的

inv(2)=15,  inv(21)=18    2*15=1 mod 29, 18*21=1 mod 29

s(2004^X)=((2^(2X+1)-1* (3^(X+1)-1)/2  *(22^(X+1)-1)/21mod 29

         =((2^(2X+1)-1* (3^(X+1)-1)*15 *(22^(X+1)-1)*18mod29

b^(-1) b的逆元素(%p)即上面的inv

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

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

因此

a=powi(2,2*x+1,29)-1% 29;

b=(powi(3,x+1,29)-1)*15 % 29;

c=(powi(22,x+1,29)-1)*18 % 29;

ans=a*b% 29*c % 29;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值