程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> NYOJ 928 小M的因子和(數論)

NYOJ 928 小M的因子和(數論)

編輯:C++入門知識

NYOJ 928 小M的因子和(數論)


小M的因子和

時間限制:1000 ms | 內存限制:65535 KB 難度:2
描述

小M在上課時有些得意忘形,老師想出道題目難住他。小M聽說是求因子和,還是非常得意,但是看完題目是求A的B次方的因子和,有些手足無措了,你能解決這個問題嗎?

輸入
有多組測試樣例
每行兩個數 A ,B ,(1≤A,B≤10^9)
輸出
輸出A的B次方的因子和,並對9901取余。
樣例輸入
2 3
樣例輸出
15


分析:對A進行質因數分解,假設A = (p1^a1) * (p2^a2)*……*(pk^ak),假設A的因子和為sum,

則sum=(1 + p1 + p1^2 + ……+p1^a1)*(1+p2+p2^2 + ……+p2^a2)*……*(1+pk+pk^2+……+pk^ak),把這個式子展開之後.每一項剛好是A的因子。

所以求A^B的因子和時,只需把ai 改為ai*b,然後再求解即可。求得時候因為次方比較大,要用分治和快速冪來求。

#include 
#include 
const int mod = 9901;

int Pow(int a, int n) {  //快速冪求a^n
    int res = 1;
    a %= mod;
    while(n) {
        if(n&1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}

int get_sum(int a, int n) {  //求(1 + a + a^2 + …… + a^n)
    if(n == 0) return 1;
    if(n&1) return get_sum(a, n / 2) * (Pow(a, (n / 2 + 1)) + 1) % mod;
    else return (get_sum(a, n / 2 - 1) * (Pow(a, n / 2) + 1) + Pow(a, n)) % mod;
}

int main() {
    int a, b;
    while(~scanf("%d%d", &a, &b)) {
        int ans = 1;
        int m = (int)sqrt(a + 0.5);
        for(int i = 2; i <= m; ++i) {
            if(a % i == 0) {
                int k = 0;
                while(a % i == 0) {
                    k++;
                    a /= i;
                }
                ans = ans * get_sum(i, k * b) % mod;
            }
        }
        if(a > 1) ans = ans * get_sum(a, b) % mod;
        printf("%d\n", ans);
    }
    return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved