Cod sursa(job #528152)

Utilizator DraStiKDragos Oprica DraStiK Data 2 februarie 2011 11:29:07
Problema Suma si numarul divizorilor Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.72 kb
#include <algorithm>
#include <bitset>
using namespace std;

#define MAX 1000005
#define DIM 500005
#define MOD 9973

bitset <MAX> viz;
int t,n,sum,nrd;
int prime[DIM];

void init ()
{
    int i,j;

    prime[++n]=2;
    for (i=3; i<MAX; i+=2)
        if (!viz[i>>1])
        {
            prime[++n]=i;
            for (j=3*i; j<MAX; j+=(i<<1))
                viz[j>>1]=1;
        }
}


inline int lgput (int n,int p)
{
    int rez;

    for (rez=1; p; p>>=1)
    {
        if (p&1)
            rez=(rez*n)%MOD;
        n=(n*n)%MOD;
    }

    return rez;
}

inline int euclid (int a,int b,int &x,int &y)
{
    int d,x0,y0;

    if (!b)
    {
        x=1; y=0;
        return a;
    }
    d=euclid (b,a%b,x0,y0);
    x=y0; y=x0-(a/b)*y0;

    return d;
}

inline int invers (int a,int n)
{
    int inv,nr;

    euclid (a,n,inv,nr);
    if (inv<0)
        inv=n+inv%n;

    return inv;
}

void solve ()
{
    long long x;
    int i,put;

    sum=nrd=1;
    scanf ("%lld",&x);
    for (i=1; i<=n && 1LL*prime[i]*prime[i]<=x; ++i)
        if (!(x%prime[i]))
        {
            for (put=0; !(x%prime[i]); ++put)
                x/=prime[i];
            sum=(sum*(lgput (prime[i],put+1)-1+MOD))%MOD;
            sum=(sum*invers (prime[i]-1,MOD))%MOD;
            nrd=(nrd*(put+1))%MOD;
        }
    if (x>1)
    {
        sum=(sum*(lgput (x,2)-1+MOD))%MOD;
        sum=(sum*invers (x-1,MOD))%MOD;
        nrd=(nrd<<1)%MOD;
    }
    printf ("%d %d\n",nrd,sum);
}

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

    init ();
    scanf ("%d",&t);
    for (i=1; i<=t; ++i)
        solve ();

    return 0;
}