poj 1845

题目大意:

给你两个数,A,B.求A^B的所有因子的和.

思路:

先用素数筛掉A.再将可以除以的素数的个数*B.就是A^B的所有基本素数因子及其个数.

1.求其所有因子的和:(假如6^3)则prime[2]=1;prime[3]=1;共同乘以3,则prime[2]=3;prime[3]=3;其因子的和为(1+2^1+2^2+2^3)*(1+3^1+3^2+3^3);

2.求等比数列的积:一般想到是(a0-q^n)/(1-q);但是当q为1000+时,就不能这么做了.要用到二分递归

当n为偶数:

(1+a+a^2+....+a^n)=(1+a^(n/2+1))*1+((1+a^(n/2+1)))*a+(1+a^(n/2+1))*a^2+.....+(1+a^(n/2+1))*a^(n/2-1)+a^(n/2);

当n为奇数:

(1+a+a^2+....+a^n)=(1+a^(n/2+1))*1+((1+a^(n/2+1)))*a+(1+a^(n/2+1))*a^2+.....+(1+a^(n/2+1))*a^(n/2);

源代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
using namespace std;
__int64 s[50000100];
__int64 m,mm,n,late;
__int64 binary(__int64 r,__int64 ci)
{   
  if(ci==1)return r%9901;
    if(ci%2==1)return (binary((r%9901)*(r%9901),ci/2)%9901)*(r%9901)%9901;
    else return binary((r%9901)*(r%9901),ci/2)%9901;
}//二分求指数
__int64 sum(__int64 x,__int64 y)
{
    if(y==0)return 1;
    if (y%2==0){return ((sum(x,(y/2)-1)%9901)*((1+binary(x,y/2+1))%9901)+(binary(x,y/2)%9901))%9901;}
    else {return (sum(x,(y/2))%9901)*((1+binary(x,y/2+1))%9901)%9901;}
} //求等比数列的和
__int64 togother()
{
	__int64 num=1; 
   for(int l=2;l*l<=mm;l++)
   {
       num*=((sum(l,s[l]*n))%9901);//注意是积
       num%=9901;
   }
   return num;
}//求所有因子的和
int main()
{
    __int64 i,j;
    late=0;
    while(cin>>m>>n)
    {
    mm=m;
    i=2;
    for(i=2;i*i<=mm;i++)
    {
      s[i]=0;
      while(m%i==0){s[i]++;m/=i;}
      if(m==1)break;
    }
    __int64 late=1;
    if(m!=1)late=sum(m,n)%9901;//有可能m本身就是一个素数,则需要另外处理
    if(mm==0&&n)cout<<"0"<<endl;//poj的这一题其实没有这种数据
    else 
    cout<<(late*togother())%9901<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值