• HDU 1452 Happy 2004(因子和的积性函数)


    题目链接

    题意 : 给你一个X,让你求出2004的X次方的所有因子之和,然后对29取余。

    思路 : 原来这就是积性函数,点这里这里这里,这里讲得很详细。

    在非数论的领域,积性函数指所有对于任何a,b都有性质f(ab)=f(a)f(b)的函数。  

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

    若对于某积性函数 f(n),就算a, b不互质,也有f(ab)=f(a)f(b),则称它为完全积性的。

    s(6)=s(2)*s(3)=3*4=12;

    s(20)=s(4)*s(5)=7*6=42;

    再看 s(50)= 1+2+5+10+25+50=93=3*31=s(2)*s(25),s(25)=1+5+25=31.

    这在数论中叫积性函数,当gcd(a,b)=1 s(a*b)=s(a)*s(b);

    如果p是素数 : s(p^n)=1+p+p^2+...+p^n= (p^(n+1)-1) /(p-1)-----其实就是等比数列求和公式 (1)

    再看本题 :

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

    2004=2^2 *3 *167

    2004^X=4^X * 3^X *167^X

    s(2004^X) ) = (s(2^2X))) * (s(3^X))) * (s(167^X))) 而 167%29=22

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

    a=s(2^2X)=(2^(2X+1)-1) //根据1

    b=s(3^X)= (3^(X+1)-1)/2 //根据1

    c=s(22^X)= (22^(X+1)-1)/21 //根据1

    %运算法则 

    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)*18)mod29

    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;

     1 //1452
     2 #include <stdio.h>
     3 #include <math.h>
     4 #include <iostream>
     5 
     6 using namespace std ;
     7 
     8 int multimod(int a,int n)//乘方模
     9 {
    10     int res = 1 ;
    11     while(n)
    12     {
    13         if(n & 1)
    14         {
    15             res *= a ;
    16             res %= 29 ;
    17         }
    18         a *= a ;
    19         a %= 29 ;
    20         n >>= 1 ;
    21     }
    22     return res ;
    23 }
    24 int main()
    25 {
    26     int x ;
    27     while(~scanf("%d",&x))
    28     {
    29         if(x == 0) break ;
    30         int a = (multimod(2,2*x+1)-1) ;
    31         int b = (multimod(3,x+1)-1)*15 ;
    32         int c = (multimod(167,x+1)-1)*18 ;
    33         printf("%d
    ",(a*b*c)%29) ;
    34     }
    35     return 0 ;
    36 }
    View Code
  • 相关阅读:
    第一次结对编程作业
    第一次个人编程作业
    第一次博客作业
    20172332 实验一《Java开发环境的熟悉》实验报告
    20172332 《程序设计与数据结构》第二周学习总结
    20172332 《程序设计与数据结构》第一周学习总结
    寒假作业03
    寒假作业02
    寒假作业01
    Java核心技术点之集合框架
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3732923.html
Copyright © 2020-2023  润新知