您的位置:首页 > 其它

poj 1845 Sumdiv

2015-08-25 19:05 423 查看
题目链接:http://poj.org/problem?id=1845

一,题意:

给定两个整数A,B,要求出A的B次幂,所有因子之和(要求%9901)。

二,分析:

1,我们知道每一个整数A都可以唯一的分解成若干素数幂的乘积,这些素数

就是A的质因数:






2,对于A 所有约数和我们有公式:






3,我们在求解:

是应用了二分等比数列求和法







我们利用递归方法可以很快求解 对于中间p的n次幂计算我们利用快速幂运算求解;

三,代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
const int mod=9901;
const int Max=7100;
typedef long long LL;
int A,B;
int sum[Max];//A 分解的质因数对应的次数
int data[Max];//A 分解的质因数
int length;

int prime[Max],Size;
bool used[Max];

void init()
{//素数打表
memset(used,true,sizeof(used));
Size=0;
for(int i=2;i<Max;i++)
{
if(used[i])
prime[Size++]=i;
for(int j=0;j<Size && prime[j]*i<Max;j++)
{
used[i*prime[j]]=false;
if(i%prime[j]==0)
break;
}
}
}

void draw()
{//A 分解质因数
int key=A;
length=0;
int bian=sqrt(A);
for(int i=0; prime[i]<=bian && key>1; i++)
{
int x=0;
while(key%prime[i]==0)
{
x++;
key=key/prime[i];
}
if(x)
{
data[length]=prime[i];
sum[length]=x*B;
length++;
}
}
if(key!=1)
{
data[length]=key;
sum[length]=B;
length++;
}
}
LL pow(int n,int x)
{//快速幂运算
LL res=1;
LL y=x;
while(n)
{
if(n&1)
res=(res*y)%mod;
y=(y*y)%mod;
n>>=1;
}
return res%mod;
}

LL DFS(int n,int x)
{//二分求等比数列和
if(n==0)
return 1;
LL res,key;
if(n%2==0)
{
key=pow(n/2,x);
res=(key*x%mod)%mod+1;
res=((res*DFS(n/2-1,x))%mod+key)%mod;
}
else
{
res=pow(n/2+1,x)+1;
res=(res*DFS(n/2,x))%mod;
}
return res%mod;
}
void solve()
{
LL res=1;
for(int i=0;i<length;i++)
{
res=(res*DFS(sum[i],data[i]))%mod;
}
printf("%ld\n",res);
}
int main()
{
init();
while(scanf("%d%d",&A,&B)!=EOF)
{
draw();
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: