Cod sursa(job #1015152)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 23 octombrie 2013 22:37:52
Problema Suma si numarul divizorilor Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.63 kb
#include <cstdio>
#include <bitset>

using namespace std;
const int Nmax = 1000000;
const int MOD = 9973;

int N,nrp;
int is_prime[80000];
bitset<Nmax> used;
void precalc()
{
    int i,j;
    is_prime[nrp++]=2;
    for(i = 1 ; 2*i+1 <= Nmax; ++i)
        if(!used[(2*i+1)])
        {
            is_prime[nrp++]=2*i+1;
            for(j = 1;(2*i+1)*(2*j+1) <= Nmax ; ++j)
                used[(2*i+1)*(2*j+1)] = 1;
        }
}

int lg_put(int x, int b)
{
    if (b == 0) return 1;
    if (b == 1) return x;
    int x1=x,x2=1;
    while(b != 1)
    {
        if(b&1)
            x2 = (x2 * x1)%MOD,--b;
        else
            x1 = (x1 * x1)%MOD,b/=2;
    }
    return (x1*x2)%MOD;
}


void solve()
{
    long long a,b;
    int nrd = 1,times = 0,sd = 1,x,y;
    scanf("%lld",&a);
    b = a;
    for(int i = 0; is_prime[i] <= b / 2 ; ++i)
    {
        times = 0;
        while(a % is_prime[i] == 0)
        {
            ++times;
            a/= is_prime[i];
        }
        if(times)
        {
            nrd = nrd * (times + 1);
            x = (lg_put(is_prime[i],times + 1) - 1 + MOD) % MOD ;
            y = (lg_put(is_prime[i]-1, MOD-2)) % MOD ; // calc invers modular

            sd = ((( sd * x )% MOD) * y) % MOD;
        }
        if(a == 1) break;
    }
    if(nrd  == 1)
    {
        nrd = 2;
        sd = 1 + b;
    }
    printf("%d %d\n",nrd,sd);
}

void read()
{
    long long a;
    scanf("%d",&N);
    while(N--)
        solve();
}

int main()
{
    freopen("ssnd.in","r",stdin);
    freopen("ssnd.out","w",stdout);

    precalc();
    read();
    return 0;
}