POJ1845 Sumdiv - 乘法逆元+快速幂【A^B的约数个数和】

POJ1845 Sumdiv

Sol:

约数个数和\(sumdiv=(1+p_1+p_1^2+\dots + p_1^{c_1})*\dots *(1+p_k+p_k^2+\dots + p_k^{c_k})\)

其中每一项都是一个首项为1,公比为\(p_i\)的等比数列的和,即

\(1*\frac{1-p_i^{c_{k}+1}}{1-p_i}=\frac{p_i^{c_{k}+1}-1}{p_i-1}\)

可以通过快速幂+逆元求解。

然而,当\(9901|(p_i-1)\)时,\(p_i-1 ~mod ~9901\)没有乘法逆元。但\(p_i ~mod~9901 \equiv 1 (mod ~9901)\),因此等比数列的和\(\equiv 1+1^2+\dots+1^{c_{k+1}}\equiv c_k+1\)

本题数据范围较大,乘法需要用64位整数乘法实现。

Tips:

1.若\(P|x\),则\(x ~mod~ P\)没有逆元(因为P,x不互质),但\(x+1 \equiv1(mod ~P)\)。

2.数据范围较大时(long long 之间相乘),需要用到64位整数乘法。

AC CODE:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int P = 9901;
typedef long long ll;
int A,B;
int read(){
    int x=0,f=1;char ch=‘ ‘;
    while(ch>‘9‘||ch<‘0‘) {if(ch==‘-‘) f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=(x<<3)+(x<<1)+(ch^‘0‘);ch=getchar();}
    return x*f;
}
ll fmul(ll a,ll b){
    ll ans=0;
    for(;b;b>>=1){
        if(b&1) ans=(ans+a)%P;
        a=(a*2)%P;
    }
    return ans;
}
ll fpow(ll a,ll b){
    ll ans=1;
    for(;b;b>>=1){
        if(b&1) ans=(ans*a)%P;
        a=(a*a)%P;
    }
    return ans;
}
int p[20],c[20];
void get_div(int x){
    int tp=x;
    int lim=sqrt(x)+1;
    for(int i=2;i<=lim;i++){
        if(tp%i==0) p[++p[0]]=i;
        while(tp%i==0){
            tp/=i;
            c[p[0]]++;
        }
    }
    if(tp>1){
        p[++p[0]]=tp;c[p[0]]=1;
    }
}
ll cal(int x){
    if((p[x]-1)%P==0){// if p[x]-1 % 9901 = 0 -> there is no inv
        return (fmul(B,c[x])%P+1)%P;
    }
    ll ans=fmul((fpow(p[x],c[x]*B+1)-1+P)%P,fpow(p[x]-1,P-2))%P;
    return ans;
}
int main(){
    freopen("data.in","r",stdin);
    freopen("sol.out","w",stdout);
    A=read();B=read();
    if(!A) {
        printf("0");return 0;
    }
    else if(A==1){
        printf("1");return 0;
    }
    else if(B==0){
        printf("1");return 0;
    }
    get_div(A);
    ll ans=1;
    for(int i=1;i<=p[0];i++){
        ans=fmul(cal(i),ans)%P;
    }
    printf("%lld",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Loi-Brilliant/p/9763923.html

时间: 2024-10-10 04:47:13

POJ1845 Sumdiv - 乘法逆元+快速幂【A^B的约数个数和】的相关文章

51 Nod 1013 3的幂的和 矩阵链乘法||逆元+快速幂

这道题我写了两种写法 一种利用逆元 a/b%mod=a*c%mod; (c是b的逆元)易得2的逆元就是5~~~04: 一种是矩阵快速幂 利用递推式得出结论 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int mod=1000000007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c&

乘法逆元+快速幂

唉... 1 #include <iostream> 2 #include <string.h> 3 #include <cstdio> 4 #include <queue> 5 #include <map> 6 #include <vector> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include

快速乘法(基于快速幂)

快速乘法的思想和快速幂的思想一样,快速幂是求一个数的高次幂,快速乘法是求两个数相乘,什么时候才用得到快速乘法呢,当两个数相称可能超过long long 范围的时候用,因为在加法运算的时候不会超,而且可以直接取模,这样就会保证数据超不了了.具体拿一个BestCoder的题目来示例.题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5187 这个题先找规律,然后在求快速乘法和快速幂结合起来.题目推出来通式是:2n-2 推的过程就是一共有四种情况: 升升,升

POJ 2447 RSA 大数分解+逆元+快速幂

链接:http://poj.org/problem?id=2447 题意: 思路:Pollard_Rho质数分解,得到两个素数因子,P,Q,求出T,E,快速幂即可得M. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <map> #include <cstdlib> #include <queue>

2014 Super Training #7 F Power of Fibonacci --数学+逆元+快速幂

原题:ZOJ 3774  http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3774 ---------------------------------------------------------------------------------------------------------------------- 这题比较复杂,看这篇比较详细:http://blog.csdn.net/acdreamers/artic

HDU 4965 Fast Matrix Caculation ( 矩阵乘法 + 矩阵快速幂 + 矩阵乘法的结合律 )

HDU 4965 Fast Matrix Calculation ( 矩阵乘法 + 矩阵快速幂 + 矩阵乘法的结合律 ) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAX_SIZE 1001 #define CLR( a, b ) memset( a, b, sizeof(a) ) #define MOD 6 typedef long lo

组合数取模(逆元+快速幂(转)

组合数公式: 我们需要求阶乘和逆元阶乘 我们就用1e9+7来求余吧 费马小定理 a^(p-1) ≡1 (mod p) 两边同除以a a^(p-2) ≡1/a (mod p) 数论1/a 是inv(a) 应该写a^(p-2) ≡ inv(a) (mod p) 所以inv(a) = a^(p-2) (mod p) 这个用快速幂求一下,复杂度O(logn) 引用其他人写的一句话 除法求模不能类似乘法,对于(A/B)mod C,直接(A mod C)/ (B mod C)是错误的:找到B的逆元b(b=B

矩阵乘法、快速幂

1 #include <cstdio> 2 #include <iostream> 3 #include <vector> 4 #include <cstring> 5 using namespace std; 6 // 矩阵的STL实现 7 typedef vector<int> vec; 8 typedef vector<vec> mat; 9 typedef long long ll; 10 const int MOD = 10

ACM学习历程—HDU5490 Simple Matrix (数学 &amp;&amp; 逆元 &amp;&amp; 快速幂) (2015合肥网赛07)

Problem Description As we know, sequence in the form of an=a1+(n−1)d is called arithmetic progression and sequence in the form of bn=b1qn−1(q>1,b1≠0) is called geometric progression. Huazheng wants to use these two simple sequences to generate a simp