zoukankan      html  css  js  c++  java
  • poj1845 Sumdiv

    Sumdiv
    Time Limit: 1000MS   Memory Limit: 30000K
    Total Submissions: 23172   Accepted: 5769

    Description

    Consider two natural numbers A and B. Let S be the sum of all natural divisors of A^B. Determine S modulo 9901 (the rest of the division of S by 9901).

    Input

    The only line contains the two natural numbers A and B, (0 <= A,B <= 50000000)separated by blanks.

    Output

    The only line of the output will contain S modulo 9901.

    Sample Input

    2 3

    Sample Output

    15

    Hint

    2^3 = 8. 
    The natural divisors of 8 are: 1,2,4,8. Their sum is 15. 
    15 modulo 9901 is 15 (that should be output). 

    Source

    分析:这道题有点复杂,涉及到约数嘛,肯定是先要分解一下,将原数变成唯一分解定律的表达形式,a = p1^x1*p2^x2*...*pn^xn,a^b = p1^x1b*p2^x2b*...*pn^xnb,那么约数和怎么求呢?如果把a^b的所有约数用唯一分解定律的表达形式写出来,就会发现p1和p2,p3,...,pn的所有的乘积的组合形式乘了一次,因式分解一下,可以得到sum = (1 + p1 + p1^2 + ... + p1^x1b) * (1 + p2 + ...+p2^x2b)*......
    括号里的式子是一个等比数列,我们可以套用公式来计算,涉及到取模,就要求逆元,不过这个地方有点小技巧,如果求-1的逆元,答案是-1,但是程序给的是1,也就是说我们最好是求正数的逆元,等比数列求和公式上下同取负号就好了.
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    
    using namespace std;
    
    const int mod = 9901;
    long long cnt[100010],wh[100010],tot,ans = 1;
    int a,b;
    
    void exgcd(long long a,long long b,long long &x,long long &y)
    {
        if (!b)
        {
            x = 1;
            y = 0;
            return;
        }
        exgcd(b,a % b,x,y);
        long long t = x;
        x = y;
        y = t - (a / b) * y;
        return;
    }
    
    long long qpow(long long a,long long b)
    {
        long long ans = 1;
        while (b)
        {
            if (b & 1)
            ans = (ans * a) % mod;
            a = (a * a) % mod;
            b >>= 1;
        }
        return ans;
    }
    
    int main()
    {    
        scanf("%d%d",&a,&b);
        for (int i = 2; i <= sqrt(a); i++)
        {
            if (a % i == 0)
            {
                wh[++tot] = i;
                while (a % i == 0)
                {
                a /= i;
                cnt[i]++;
                }
            }
        }
        if (a)
        {
            wh[++tot] = a;
            cnt[a]++;
        }
        
        for (int i = 1; i <= tot; i++)
        {
            long long x,y;
            exgcd(wh[i] - 1,mod,x,y);
            ans = (ans * (( qpow(wh[i],cnt[wh[i]] * b + 1) - 1)* x) % mod) % mod;
        }
        printf("%lld
    ",ans);
        
        
        return 0;
    } 
     
  • 相关阅读:
    基于密度的optics聚类算法
    unicode编码和utf-8编码详解
    聚类分析之k-prototype算法解析
    python学习笔记之正则表达式1
    聚类分析之模糊C均值算法核心思想
    Matlab编程笔记之GUI程序转exe
    Matlab学习笔记之安装教程
    SVPWM原理分析-基于STM32 MC SDK 5.0
    Allego Quick Reports
    SVPWM-实战
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7498446.html
Copyright © 2011-2022 走看看