HDU 2421 Deciphering Password 积性函数

/*
------------------------------------------------------------------
    stratege: 积性函数, 素数分解, 欧拉函数
            任意一个数,可以写成  N = p1^a1 * p2 ^a2 *...* pn^an 
            又由于欧拉函数是积性函数,
            所以eulur (n) = (eulur(p1^a1) *...* eulur (pn^an))
            f(p1^a1)=1^3+……+(a1+1)^3=(a1+1)^2 * (a1+2)^2 / 4 ;
            n ^ m ----> 只要求出一个n,m的n次都是一样的。
    Author : Johnsondu 
    Time : 4.11.2012  18:00 

5752625	2012-04-11 17:00:59	Accepted	2421	62MS	232K	1713B	C++	johnsondu

-------------------------------------------------------------------
*/
#include <iostream>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <vector>
using namespace std;
#define inf 0x7fffffff
#define ll __int64
const int Mod = 10007 ;

#define MAXN 1105
#define MAX 1000

int primeLen ;
int isPrime [MAXN] ;
int prime [MAX];

void init ()  // 筛素数
{
    int i ;
    primeLen = 0 ;
    prime [primeLen ++] = 2 ;
    isPrime[0] = isPrime[1] = 1 ;
    for (i = 4; i < MAXN; i += 2)
        isPrime[i] = 1 ;
    for (i = 3; i < MAXN; i += 2)
    {
        if (!isPrime[i])
        {
            prime[primeLen ++] = i ;
            int tmp = i << 1 ;
            while (tmp < MAXN)
            {
                isPrime[tmp] = 1 ;
                tmp += i ;
            }
        }
    }
}

int main()
{
    int n, i, m ;
    ll res ;
    int cas = 1;
    init () ;
    while (scanf ("%d%d", &n, &m) != EOF)
    {
        res = 1 ;
        for (i = 0; prime[i]*prime[i] <= n; i ++)
        {
            ll cnt = 0 ;
            while (n % prime[i] == 0)  //求相同素因子下的素因子个数
            {
                cnt ++ ;
                n /= prime[i] ;
            }
            if (cnt)
            {
                ll tp = ((ll)(cnt*m+1) * (ll)(cnt*m+2)/ 2) % Mod ; // 无限WA处,都要ll,否则估计会溢出
                tp = (tp * tp) % Mod;                              //此时m个n相乘,则在这个素数下的因子数为cnt * m ;
                res =  (res * tp) % Mod ;                          //套公式f(p1^a1)=1^3+……+(a1+1)^3=(a1+1)^2 * (a1+2)^2 / 4 ;

            }
        }
        if (n > 1) //此时当前的素数下都除不尽,所以这个数肯定是一个单独的素数
        {
            ll tp = ((ll)(m+1) * (ll)(m+2) / 2) % Mod ;
            tp = (tp * tp) % Mod ;
            res = (res * tp ) % Mod ;
        }
        printf ("Case %d: %I64d\n", cas ++, res) ;
    }
    return 0;
}
// TLE代码,用筛选法做
#include <iostream>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <vector>
using namespace std;
#define inf 0x7fffffff
#define ll __int64

#define MAXN 5000005

ll ans[MAXN];
int num[MAXN] ;

void init ()
{
    int i, j ,temp;
    for (i = 1; i < MAXN; i ++)
    {
        num[i] ++;
        temp = num[i]*num[i]*num[i];
        ans[i] += temp;
        for (j = i * 2; j < MAXN; j += i)
        {
            num[j] ++;
            ans[j] += temp;
        }
    }
}

//int scan()  // 外挂输入
//{
//    int num = 0;
//    char cc;
//    while(1)
//    {
//        cc = getchar();
//        if(cc >= '0' || cc <= '9') break;
//    }
//    num = cc - '0';
//
//    while(cc = getchar())
//    {
//        if(cc >= '0' && cc <= '9')
//            num = num*10 + cc - '0';
//        else break;
//    }
//    return num;
//}

int main()
{
    int n, tcase, i ;
    init () ;
    tcase = scan();
    while (tcase --)
    {
        n = scan();
        printf ("%I64d\n", ans[n]);
    }

    return 0;
}




   

你可能感兴趣的:(HDU 2421 Deciphering Password 积性函数)