lightoj1054 Efficient Pseudo Code(欧拉函数+Divisor function)

题目

nm 所有约数的和在mod 1e9+7 的结果;

思路

数学知识点
n可以写成 n=px11px22... ,那么 nm=pmx11pmx22...
这样就可以用下面这个公式求解了,具体数学看上面的链接,这里x取1;
σx(n)=ri=1p(ai+1)xi1pxi1


int prime[10000];
void init() {
    bool mark[100000] = {
   
   false};
    for (int i = 2;i < 100000;++i) {
        if (!mark[i]) {
            prime[++prime[0]] = i;
            mark[i] = true;
            for (long long j = 1ll*i * i;j < 100000;j += i)
                mark[j] = true;
        }
    }   
}
long long calc(long long a, long long b) {
    long long ans;
    ans = QMOD(a, b) - 1;
    // 这个地方用的逆元
    ans = ans * QMOD(a - 1, MOD - 2) % MOD;
    while(ans < 0) ans += MOD;
    if (ans > MOD) ans %= MOD;
    return ans;
}
int main(int argc, const char * argv[])
{    
    // freopen("/Users/jamesqi/Desktop/in.txt","r",stdin);
    // freopen("/Users/jamesqi/Desktop/out.txt","w",stdout);
    // ios::sync_with_stdio(false);
    // cout.sync_with_stdio(false);
    // cin.sync_with_stdio(false);

    int kase;cin >> kase;
    init();
    while(kase--) {
        long long n, m;cin >> n >> m;
        vector<ii> buff;
        for (int i = 1;i <= prime[0] && prime[i] * prime[i] <= n;++i) {
            if (n % prime[i] == 0) {
                ii t(prime[i], 0);
                while(n % prime[i] == 0) {
                    n /= prime[i];
                    ++t.second;
                }
                buff.push_back(t);
            }
        }
        if (n > 1) buff.push_back(ii(n, 1));

        long long ans = 1ll;
        for (int i = 0;i < (int)buff.size();++i)
            ans = ans * calc(buff[i].first, buff[i].second*m + 1) % MOD;
        printf("Case %d: %lld\n", ++nCase, ans);
    }

    // showtime;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/KIJamesQi/article/details/55099570
今日推荐