1 条题解

  • 0
    @ 2025-8-24 21:26:53

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar C_Cong
    1+1=⑨ ⑨⑨=⑥ ⑥/⑥=1 雾の湖城管*

    搬运于2025-08-24 21:26:52,当前版本为作者最后更新于2020-05-06 13:33:45,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    博客传送门

    题意简述:

    aba^b的所有因子和

    解题思路:

    既然要求因子和,那我们必然要先分解质因数

    根据整数的唯一分解定理,整数a进行质因数分解对应的式子唯一,有:

    $$a = p_1^{k_1} * p_2^{k_2} *p_3^{k_3}* … * p_n^{k_n} $$

    又因为本题要分解的是aba^b,所以上面的式子又可以写成这样:

    $$a^b= p_1^{k_1*b} * p_2^{k_2*b} *p_3^{k_3*b}* … * p_n^{k_n*b} $$

    证明很简单,就是把上面第一个式子乘上bb次即可得第二个式子

    接下来我们要求的是因子和,

    所以就有:

    $$ans= (1+p_1^1 + p_1^2 +p_1^3+ … + p_1^{k_1*b})*(1+p_2^1 + p_2^2 +p_2^3+ … + p_1^{k_2*b})*...*(1+p_n^1 + p_n^2 +p_n^3+ … + p_n^{k_n*b}) $$

    对于上面的式子是不是有点熟悉?

    对,你没有看错,就是等比数列之间的乘积

    根据等比数列求和公式:

    sum=pn1p1sum=\frac{p^{n}-1}{p-1}

    我们就能求出各数列的和,

    对于pn+1p^{n+1},我们用快速幂求

    又因为本题要求的答案要对9901取模

    故我们又可以通过逆元将除p1p-1转化为乘p1p-1的逆元

    接下来要求逆元,根据定义,在mod pmod\ p的意义下,对于一个整数aa,有:

    ax1(mod p)a*x≡1(mod\ p)

    xx即为aa的逆元,反之成立

    注意此处的a,pa,p均与上文的意义不同,仅作为公式中的未知数

    a,pa,p不互质时,逆元不存在,即上面的式子要满足:

    gcd(a,p)=1gcd(a,p)=1

    那么这个xx怎么求?

    那我们再引入一个定理,费马小定理:

    假如aa是一个整数,pp是一个质数,那么当aapp的倍数时,有:

    apa(mod p)a^p≡a(mod\ p)

    aa不是pp的倍数时,有:

    ap11(mod p)a^{p-1}≡1(mod\ p)

    对于本题,显然我们要用的是第二种情况,第二种情况又可以变形为:

    aap21(mod p)a*a^{p-2}≡1(mod\ p)

    上式恰好对应逆元的定义式,故aamod pmod\ p意义下的逆元为ap2a^{p-2}

    ap2a^{p-2}我们用快速幂即可求得

    那逆元不存在怎么办,不用担心,因为对应上面的式子p1p-1,有:

    (p1) mod 9901=0(p-1) \ mod \ 9901=0

    即:

    p mod 9901=1p \ mod \ 9901=1

    所以该等比数列之和(mod pmod\ p意义下)为:

    $$sum= 1+({p\ mod\ 9901})^1 +({p\ mod\ 9901})^2 +({p\ mod\ 9901})^3+ … + ({p\ mod\ 9901})^{n} $$

    即:

    sum=1+nsum=1+n

    至此,本题就分析完了

    代码实现:

    #include<iostream>
    #include<cstdio>
    #define mod 9901
    using namespace std;
    
    int a,b,sa,n[10010][2],cot=0,ans=1;
    
    int quick_pow(int ml,int nl)//快速幂
    {
    	int s=1;
    	while(nl>0)
    	{
    		if(nl%2==1)
    		{
    			s=(s%mod)*(ml%mod)%mod;
    		}
    		ml=ml*ml%mod;
    		nl=nl>>1;
    	}
    	return s%mod;
    }
    
    int sum(int x,int y)
    {
    	int k=0;
    	y=y*b;
    	if(x%mod==1)
    	{
    		k=(y+1)%mod;//当逆元不存在时
    	}
    	else
    	{
    		k=(quick_pow(x%mod,y+1)-1)%mod*quick_pow((x-1)%mod,mod-2)%mod;//当逆元存在时
    	}
    	
    	return k%mod;
    }
    
    int main()
    {
    	scanf("%d%d",&a,&b);
    	if(a==0)//特判,0的因数和就是0
    	{
    		printf("0\n");
    		return 0;
    	}
    	for(int i=2;i*i<=a;i++)//分解质因数
    	{
    		if(a%i==0)
    		{
    			cot++;
    			n[cot][0]=i;//记录质因数
    			n[cot][1]=1;//记录幂次
    			a=a/i;
    			while(a%i==0)
    			{
    				n[cot][1]++;//记录幂次
    				a=a/i;
    			}
    		}
    	}
    	if(a!=1)//可能a仍为因子
    	{
    		cot++;
    		n[cot][0]=a;
    		n[cot][1]=1;
    	}
    	for(int i=1;i<=cot;i++)
    	{
    		ans=ans*sum(n[i][0],n[i][1])%mod;
    	}
    	printf("%d\n",(ans%mod+mod)%mod);
    	return 0;
    }
    

    有用的话点个赞顶上去才能让更多人看到哦QAQ

    • 1

    信息

    ID
    586
    时间
    1000ms
    内存
    128MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者