题意:求a^b的所有约数的和对9901取余。
分析:我们转化为a^b的所有质因子的等比数列的成积,例如100^1,转化为(1+2+4) * (1 + 5 + 25)。由于a^b的质因子与a的质因子相同,只是每个的数量是a的质因子的b倍。具体做法是先求所有素数,求a的所有质因子,对于每个质因子求num[i]*b+1项的等比数列。并求乘积。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include
<
iostream
>
#include < cstdio >
#include < cstdlib >
#include < cstring >
#include < cmath >
using namespace std;
#define maxn 10000
#define w 9901
int a, b;
bool is [maxn];
int prm[maxn];
int fac[maxn], num[maxn];
int getprm( int n)
{
int i, j, k = 0 ;
int s, e = ( int ) (sqrt( 0.0 + n) + 1 );
memset( is , 1 , sizeof ( is ));
prm[k ++ ] = 2 ;
is [ 0 ] = is [ 1 ] = 0 ;
for (i = 4 ; i < n; i += 2 )
is [i] = 0 ;
for (i = 3 ; i < e; i += 2 )
if ( is [i])
{
prm[k ++ ] = i;
for (s = i * 2 , j = i * i; j < n; j += s)
is [j] = 0 ;
}
for (; i < n; i += 2 )
if ( is [i])
prm[k ++ ] = i;
return k;
}
int power( int a, int n)
{
int ret = 1 ;
int m = a % w;
while (n)
{
if ( 1 & n)
ret *= m;
ret %= w;
n >>= 1 ;
m *= m;
m %= w;
}
return ret;
}
int cal( int d, int num)
{
d %= w;
if (num == 0 )
return 1 ;
if (num == 1 )
{
return (d + 1 ) % w;
}
int mid;
if (num & 1 )
{
mid = power(d, num / 2 + 1 );
return (mid + 1 ) * cal(d, num / 2 ) % w;
}
int x = power(d, num / 2 );
mid = power(d, num / 2 + 1 );
return ((mid + 1 ) * cal(d, num / 2 - 1 ) + x) % w;
}
int main()
{
// freopen("t.txt", "r", stdin);
scanf( " %d%d " , & a, & b);
int n = getprm( int (sqrt(a)) + 1 );
int temp = 0 ;
for ( int i = 0 ; i < n; i ++ )
if (a % prm[i] == 0 )
{
fac[temp] = prm[i];
while (a % prm[i] == 0 )
{
a /= prm[i];
num[temp] ++ ;
}
temp ++ ;
}
n = temp;
int ans = 1 ;
for ( int i = 0 ; i < n; i ++ )
ans = ans * cal(fac[i], num[i] * b) % w;
if (a != 1 )
ans = ans * cal(a, b) % w;
printf( " %d\n " , ans);
return 0 ;
}
#include < cstdio >
#include < cstdlib >
#include < cstring >
#include < cmath >
using namespace std;
#define maxn 10000
#define w 9901
int a, b;
bool is [maxn];
int prm[maxn];
int fac[maxn], num[maxn];
int getprm( int n)
{
int i, j, k = 0 ;
int s, e = ( int ) (sqrt( 0.0 + n) + 1 );
memset( is , 1 , sizeof ( is ));
prm[k ++ ] = 2 ;
is [ 0 ] = is [ 1 ] = 0 ;
for (i = 4 ; i < n; i += 2 )
is [i] = 0 ;
for (i = 3 ; i < e; i += 2 )
if ( is [i])
{
prm[k ++ ] = i;
for (s = i * 2 , j = i * i; j < n; j += s)
is [j] = 0 ;
}
for (; i < n; i += 2 )
if ( is [i])
prm[k ++ ] = i;
return k;
}
int power( int a, int n)
{
int ret = 1 ;
int m = a % w;
while (n)
{
if ( 1 & n)
ret *= m;
ret %= w;
n >>= 1 ;
m *= m;
m %= w;
}
return ret;
}
int cal( int d, int num)
{
d %= w;
if (num == 0 )
return 1 ;
if (num == 1 )
{
return (d + 1 ) % w;
}
int mid;
if (num & 1 )
{
mid = power(d, num / 2 + 1 );
return (mid + 1 ) * cal(d, num / 2 ) % w;
}
int x = power(d, num / 2 );
mid = power(d, num / 2 + 1 );
return ((mid + 1 ) * cal(d, num / 2 - 1 ) + x) % w;
}
int main()
{
// freopen("t.txt", "r", stdin);
scanf( " %d%d " , & a, & b);
int n = getprm( int (sqrt(a)) + 1 );
int temp = 0 ;
for ( int i = 0 ; i < n; i ++ )
if (a % prm[i] == 0 )
{
fac[temp] = prm[i];
while (a % prm[i] == 0 )
{
a /= prm[i];
num[temp] ++ ;
}
temp ++ ;
}
n = temp;
int ans = 1 ;
for ( int i = 0 ; i < n; i ++ )
ans = ans * cal(fac[i], num[i] * b) % w;
if (a != 1 )
ans = ans * cal(a, b) % w;
printf( " %d\n " , ans);
return 0 ;
}