HDU-1452 因子和 积性函数性质
详见代码:
#include <cstdio> #include <cstring> #include <cstdlib> #define MOD 29 using namespace std; /* 求2004^x次方的所有因子对29取余,可能是由于这一年是闰年才选择的29 我们可以对2004进行分解 2004 = 2^2 * 3 * 167,很明显2^2 和 3 和 167 都是相互互质的 因此就可以利用到一个数的因子和是一个积性函数这个性质,设S(N)为这个函数 又因为S(p^n) = 1+p+p^2+...+p^n,所以一个数被用素数的指数幂来表示的话就能够被分解化 的表示出来S(p^n) = (p^(n+1)-1)/(p-1) { %运算法则 1. (a*b) %p= ( a%p) *(b%p) %运算法则 2. (a/b) %p= ( a *b^(-1)%p) } 由上面的公式我们可以的出来S(p^n)%29 = (p^(n+1)-1)*(p-1)^(-1)%29 而x^(-1)就是x%p的逆元满足 x*inv(x) = 1%p 因子2-1=1,所以可以直接算 因子3-1=2,逆元为15,因为2*15%29=1 因子167%29=22; 22-1=21的逆元是18,因为21*18%29=1 */ int _pow(int a, int b) { int ret = 1; while (b) { if (b & 1) { ret *= a; ret %= MOD; } b >>= 1; a *= a; a %= MOD; } return ret; } int main() { int N, ret; // 表示2004的N次方 while (scanf("%d", &N), N) { ret = 1; ret *= (_pow(2, 2*N+1)-1+MOD)%MOD; ret %= MOD; ret *= ((_pow(3, N+1)*15-15)+MOD)%MOD; ret %= MOD; ret *= ((_pow(22, N+1)*18-18)+MOD)%MOD; ret %= MOD; printf("%d\n", ret); } return 0; }