POJ 1845-Sumdiv 题解(数论,约数和公式,逆元,高中数学)

题目描述

给定A,B,求A^B的所有因数的和,再MOD 9901

输入

一行两个整数 A 和 B。

输出

一行,一个整数

样例输入

2 3

样例输出

15

提示

对于100%的数据满足:0 <= A,B <= 50000000

这道题首先要想到有一个因数和公式

f[a] = ( 1 + p1 + p1^2 + .... + p1^q1 ) * ( 1 + p2 + p2^2 + .... + p2^q2 ) * ...... * ( 1 + pn + pn^2 +.....+ pn^qn )

由此我们知道,这道题需要分解质因数(唯一分解定理???

A^B可以直接分A,每个分出数的指数再×B就行(这应该都会

所以我们可以先打个素数表..

因为a,b都在50000000,计算器一算7000多的表就够了..

我们再观察因数和公式,如果一个一个求救太麻烦了,我们就发现了这是等比数列啊!!!

等比数列公式相信大家都会...

因为除数可能为负数,所以式子要上下都×-1整理一下

但这又有可能出现不是整数的情况,我们就需要用乘法逆元了(当时我卡在这了

这里先贴一个写的挺好的乘法逆元

inline long long extend_gcd(long long a,long long b,long long &x,long long &y)
{
    if(a==0&&b==0)
        return -1ll;
    if(b==0)
    {
        x=1ll;
        y=0ll;
        return a;
    }
    long long d=extend_gcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
inline long long mod_reverse(long long a,long long n)
{
    long long x,y,d=extend_gcd(a,n,x,y);
    if(d==1)
        return (x%n+n)%n;
    else
        return -1ll;
}

快速幂和乘法取模就不说了

下面贴代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long
ll vis[8000]={0};
ll ys[8000]={0},zs[8000]={0};
ll vis1[8000]={0};
ll ac[8000]={0};
using namespace std;
ll n;
ll qmod(ll i,ll j)
{
    ll ans=1;
    while(j)
    {
        if(j&1)
        {
            ans*=i;
            ans%=9901;
        }
        i=i*i%9901;
        j>>=1;
    }
    return ans%9901;
}
void prime()
{
    ll i,j,k=0;
    for(i=2;i<=7100;i++)
    {
        vis[i]=i;
    }
    i=2;
    while(i*i<=7100)
    {
        if(vis[i]!=0)
        {
            j=i<<1;
            while(j<=7100)
            {
                if(vis[j]!=0)
                {
                    k++;
                }
                vis[j]=0;
                j=j+i;
            }
        }
        i++;
    }
}
int main()
{
    ll k=1;
    ll i,j;
    ll A,b;
    ll a,n;
    cin>>a>>b;
    A=a;
    n=sqrt(a);
    prime();
    for(i=2;i<=n;i++)
    {
        while((vis[i]!=0)&&(a%vis[i]==0))
        {
            vis1[i]=1;
            ys[k]=vis[i]%9901;
            zs[k]++;
            a=a/vis[i];
        }
        if(vis1[i]==1)
        {
            k++;
        }
    }
    k--;
    ll step=0;
    ll re=0,cf=0;
    if(a!=1&&a!=A)
    {
        ys[k+1]=a%9901;
        zs[k+1]=1;
        step=1;
    }
    else
    if(a==A)
    {
        ys[1]=a%9901;
        zs[1]=1;
        k=1;
    }
    if(step==1)
    {
        k++;
    }
    ll count=0;
    for(i=1;i<=k;i++)
    {
        if(zs[i]!=0)
        {
            zs[i]=zs[i]*b;
            count++;
        }
    }
    for(i=1;i<=count;i++)
    {
        ll a1=qmod(ys[i]%9901,zs[i]+1);
        a1=a1-1;
        ll temp=(ys[i]-1)%9901;
        ll a2=qmod(temp,9899);
        ac[i]=((a1%9901)*(a2%9901))%9901;
    }
    ll sum=ac[1];
    for(i=2;i<=count;i++)
    {
        sum=((sum%9901)*(ac[i]%9901))%9901;
    }
    cout<<sum;
}
时间: 2024-11-10 13:23:34

POJ 1845-Sumdiv 题解(数论,约数和公式,逆元,高中数学)的相关文章

POJ 1845 Sumdiv(数论)

Sumdiv Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 15745   Accepted: 3894 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 99

POJ 1845 - Sumdiv ( 数论 + 唯一分解定理 + 快速幂取模 )

POJ 1845 - Sumdiv ( 数论 + 唯一分解定理 + 快速幂取模 ) 这是一道数论的好题,需要较好的数学基础 题意: 给定A,B,求A^B的所有因数的和,再MOD 9901 分析: 这里用到了数论当中相当一部分知识 a. 唯一分解定理 任何一个整数都可以分解为若干个素数的幂的乘积的形式 A = ( p1 ^ q1 + p2 ^ q2 + ..... + pn ^ qn ) p为素数 A^B = ( p1 ^ (q1*B) + p2 ^ (q2*B) + ..... + pn ^ (

POJ 1845 Sumdiv【同余模运算+递归求等比数列和+快速幂运算】

快速幂运算在第一次训练时候就已经遇到过,这里不赘述 同余模运算也很简单,这里也不说了,无非是(a+b)%m (a*b)%m 把m弄到里面变成(a%m+b%m)%m   (a%m*b%m)%m 今天学的最重要的还是递归二分求等比数列 题目大意是给出A和B,求A^B的约数和 解这个题,首先,对A进行素因子分解得到 (PI(pi^ai))^B 然后我们有约数和公式: 对A=PI(p1^k1) A的所有因子之和为S = (1+p1+p1^2+p1^3+...p1^k1) * (1+p2+p2^2+p2^

poj 1845 Sumdiv (算术基本定理求一个数因子和)

求一个数的所有因子和可以用算术基本定理,下面是它的两个重要应用: (1)一个大于1的正整数N,如果它的标准分解式为: N=(P1^a1)*(P2^a2)......(Pn^an) 那么它的正因数个数为(1+a1)(1+a2).....(1+an). (2) 它的全体正因数之和为d(N)=(1+p1+...p1^an)(1+p2+...p2^a2)...(1+pn+...+pn^an) 和求一个数正因数个数的方法类似. 可以先打表出sqrt(n)以内的所有素数(当然也可以不打表),因为n的素因数中

POJ 1845 Sumdiv (快速幂+质因数+约数和公式+同余模)

Sumdiv Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 16109   Accepted: 3992 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 99

poj 1845 Sumdiv (同余定理,快速幂取余)

链接:poj 1845 题意:求A^B的所有因子的和对9901取余后的值 如:2^3=8,8的因子有 1,2,4,8,所有和为15,取余后也是15 应用定理主要有三个: (1)整数的唯一分解定理: 任意正整数都有且只有一种方式写出其素因子的乘积表达式. A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)   其中pi均为素数 (2)约数和公式: 对于已经分解的整数A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn) 有A的所有因子之和为 S = 

POJ 1845 Sumdiv (快速分解因式+快速幂取模)

题目地址:POJ 1845 转载自:http://blog.csdn.net/lyy289065406/article/details/6648539 大致题意: 求A^B的所有约数(即因子)之和,并对其取模 9901再输出. 解题思路: 要求有较强 数学思维 的题 应用定理主要有三个: 要求有较强 数学思维 的题 应用定理主要有三个: (1)   整数的唯一分解定理: 任意正整数都有且只有一种方式写出其素因子的乘积表达式. A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^

[ACM] POJ 1845 Sumdiv(求A的B次方的所有因子的和,一大堆数学公式...,可做模板)

Sumdiv Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 13792   Accepted: 3399 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 99

POJ 1845 Sumdiv

题目链接:http://poj.org/problem?id=1845 题意:给出A,B两个整数(0 <= A,B <= 50000000),输出A^B(A的B次,不是异或)的所有因子和模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)

poj 1845 Sumdiv ,质因子分解

题意: 求A^B的所有约数之和. 题解: A = P1^a1 * P2^a2 * ... * Pn^an. A^B的所有约数之和为: sum = [1+p1+p1^2+...+p1^(a1*B)] * [1+p2+p2^2+...+p2^(a2*B)] *...* [1+pn+pn^2+...+pn^(an*B)]. 用递归二分求等比数列1+pi+pi^2+pi^3+...+pi^n: (1)若n为奇数,一共有偶数项,则: 1 + p + p^2 + p^3 +...+ p^n = (1+p^(