• POJ 1845:Sumdiv 快速幂+逆元


    Sumdiv
    Time Limit: 1000MS   Memory Limit: 30000K
    Total Submissions: 16466   Accepted: 4101

    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). 

    要求的是A^B的所有因子的和之后再mod 9901的值。

    因为一个数A能够表示成多个素数的幂相乘的形式。即A=(a1^n1)*(a2^n2)*(a3^n3)...(am^nm)。所以这个题就是要求

    (1+a1+a1^2+...a1^n1)*(1+a2+a2^2+...a2^n2)*(1+a3+a3^2+...a3^n2)*...(1+am+am^2+...am^nm) mod 9901

    对于每一个(1+a1+a1^2+...a1^n1) mod 9901 

    等于 (a1^(n1+1)-1)/(a1-1) mod 9901,这里用到逆元的知识:a/b mod c = (a mod (b*c))/ b 

    所以就等于(a1^(n1+1)-1)mod (9901*(a1-1)) / (a1-1)。

    至于前面的a1^(n1+1),快速幂。

    代码:

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <string>
    #include <cstring>
    #pragma warning(disable:4996)
    using namespace std;
    #define M 9901
    
    long long p[100008];
    int prime[100008];
    
    void isprime()
    {
    	int cnt = 0, i, j;
    	memset(prime, 0, sizeof(prime));
    	
    	for (i = 2; i < 100008; i++)
    	{
    		if (prime[i] == 0)
    		{
    			p[++cnt] = i;
    			for (j = 2 * i; j <100008;j=j+i)
    			{
    				prime[j] = 1;
    			}
    		}
    	}
    }
    long long getresult(long long A,long long n,long long k)
    {
    	long long b = 1;
    	while (n > 0)
    	{
    		if (n & 1)
    		{
    			b = (b*A)%k;
    		}
    		n = n >> 1;
    		A = (A*A)%k;
    	}
    	return b;
    }
    void solve(long long A, long long B)
    {
    	int i;
    	long long ans = 1;
    	for (i = 1; p[i] * p[i] <= A; i++)
    	{
    		if (A%p[i] == 0)
    		{
    			int num = 0;
    			while (A%p[i] == 0)
    			{
    				num++;
    				A = A / p[i];
    			}
    			long long m = (p[i] - 1) * 9901;
    			ans *= (getresult(p[i], num*B + 1, m) + m - 1) / (p[i] - 1);
    			ans %= 9901;
    		}
    	}
    	if (A > 1)
    	{
    		long long m = 9901 * (A - 1);
    		ans *= (getresult(A, B + 1, m) + m - 1) / (A - 1);
    		ans %= 9901;
    	}
    	cout << ans << endl;
    }
    
    int main()
    {
    	long long A, B;
    	
    	isprime();
    	
    	while (scanf("%lld%lld", &A, &B) != EOF)
    	{
    		  solve(A, B);
    	}
    	return 0;
    }
    


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    javascript 学习笔记714章
    数据库设计的四个范式
    【转】utf8的中文是一个汉字占三个字节长度
    java 中文url的解决
    so动态链接库的使用
    linux常用命令
    控制台编译Qt程序
    构造函数初始化列表 组合类构造函数
    const volatile
    std::pair
  • 原文地址:https://www.cnblogs.com/lightspeedsmallson/p/4899573.html
Copyright © 2020-2023  润新知