HDU 1852,1452 a^n的约数和

想法:a^n,先把a拆成所有的素数乘积,如2004=2*2*3*167,2008=2*2*2*251.
then: s(2004^n)=s(2^(2*n))*s(3^n)*s(167^n)
then: 对于一个素数p,则s(p^n)=1+p+p^2+p^3+...+p^n=(p^(n+1)-1)/(p-1)  等比数列公式。
then: s(2004^n)=(2^(2*n+1)-1)/1 * (3^(n+1)-1)/2 * (167^(n+1)-1)/167
一个小知识:(a*b/c)%mod      设m1=a,m2=b/c; 则m1mod=(m1%mod+mod)%mod; m2mod=(b%(c*mod)+c*mod)%mod,m2mod/=c;   最后结果=(m1mod%mod)*(m2mod%mod)%mod;


//1852
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,k;
int quickpow(int a,int b,int K)
{
	if(K==0) return 1;
	__int64 res=1,tmp;
	tmp=a%K;
	while(b)
	{
		if(b&1) res=(res%K)*(tmp%K)%K;
		b>>=1;
		tmp=(tmp%K)*(tmp%K)%K;
	}
	return (int)res;
}
int main()
{
	while(~scanf("%d%d",&n,&k),n+k)
	{
		int m1=quickpow(2,3*n+1,k)-1;
		m1=(m1+k)%k;
		int m2=quickpow(251,n+1,250*k)-1;
		m2=(m2+250*k)%(250*k);
		m2/=250;
		int M=(m1%k)*(m2%k)%k;
		printf("%d\n",quickpow(2008,M,k));
	}
	return 0;
} 

//1452
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int quickpow(int a,int b)
{
    if(b==0) return 1;
    int res=1;
    while(b)
    {
        if(b&1) res=res*a%29;
        b>>=1;
        a=a*a%29;
    }
    return res%29;
}
int main()
{
    int x;
    while(~scanf("%d",&x),x)
    {
        int k=((quickpow(2,2*x+1)-1)*(quickpow(3,x+1)-1)*(quickpow(167,x+1)-1)*15*18)%29;
        printf("%d\n",k);
    }
    return 0;
}

你可能感兴趣的:(HDU 1852,1452 a^n的约数和)