Cod sursa(job #2270764)

Utilizator giotoPopescu Ioan gioto Data 27 octombrie 2018 15:19:35
Problema Suma divizorilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.62 kb
#include <bits/stdc++.h>
using namespace std;

int t, np;
const int MOD = 9901;
struct fp{
    int x, k;
};
fp p[1005];
bool f[7080];
int pr[7000];
inline void ciur(){
    pr[++np] = 2;
    for(int i = 3; i <= 7080 ; i += 2){
        if(!f[i]){
            pr[++np] = i;
            for(int j = i * 3; j <= 7080 ; j += i * 2)
                f[j] = 1;
        }
    }
}
inline void desc(long long x, int &NR){
    for(int i = 1; 1LL * pr[i] * pr[i] <= x && i <= np ; ++i){
        if(x % pr[i] == 0){
            p[++NR] = {pr[i], 0};
            while(x % pr[i] == 0){
                ++p[NR].k;
                x /= pr[i];
            }
        }
    }
    if(x > 1) p[++NR] = {x, 1};
}
inline int lgput(int x, int p){
    int ans = 1, aux = x;
    for(int i = 1; i <= p ; i *= 2){
        if(i & p) ans = (1LL * ans * aux) % MOD;
        aux = (1LL * aux * aux) % MOD;
    }
    return ans;
}
int main()
{
    freopen("sumdiv.in", "r", stdin);
    freopen("sumdiv.out", "w", stdout);

    int a, b;
    scanf("%d%d", &a, &b);
    if(a == 0){printf("0"); return 0;}
    if(b == 0){printf("1"); return 0;}

    int NR = 0;
    ciur();
    desc(a, NR);
    int sumdiv = 1;
    for(int i = 1; i <= NR ; ++i){
        p[i].x %= MOD;
        if(p[i].x == 0) continue ;
        if(p[i].x == 1) sumdiv = (sumdiv * (p[i].k * b + 1)) % MOD;
        else{
            sumdiv = (1LL * sumdiv * (1LL * (lgput(p[i].x, p[i].k * b + 1) - 1) * lgput(p[i].x - 1, MOD - 2)) % MOD) % MOD;
            if(sumdiv < 0) sumdiv = sumdiv % MOD + MOD;
        }
    }
    printf("%d", sumdiv);

    return 0;
}