Cod sursa(job #1705427)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 20 mai 2016 16:20:08
Problema Suma si numarul divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 kb
#include <bits/stdc++.h>
using namespace std;
typedef long long i64;

const int MOD = 9973;

FILE *fi, *fo;
bitset<1001005> c;
vector<int> p;


void erat(int lim) {
    c[0] = 1;
    c[1] = 1;
    for(int i=4; i<=lim; ++i, ++i)
        c[i] = 1;
    for(int i=3; i<=lim; ++i, ++i) {
        if(c[i])
            continue;
        for(i64 j=1LL*i*i; j<=lim; j+=i+i)
            c[j] = 1;
    }
    for(int i=3; i<=lim; ++i)
        if(!c[i])
            p.push_back(i);
}

inline i64 expow(i64 b, int e) {
    i64 ans = 1;
    while(e) {
        if(e&1)
            ans=ans*b%MOD;
        e>>=1;
        b=b*b%MOD;
    }
    return ans;
}

inline i64 mod(i64 a, i64 b) {
    return (a%b>=0)?a%b:b+a%b;
}

inline void query(i64 arg) {
    vector<pair<int, int> > v;
    i64 d, e, s, nu, nd;
    int c;

    if(arg%2==0) {
        c=0;
        while(arg%2==0) {
            ++c;
            arg/=2;
        }
        v.push_back(make_pair(2, c));
    }
    for(int i=0; 1LL*p[i]*p[i]<=arg; ++i) {
        if(arg%p[i])
            continue;
        c=0;
        while(!(arg%p[i])) {
            arg/=p[i];
            ++c;
        }
        v.push_back(make_pair(p[i], c));
    }
    if(arg>1)
        v.push_back(make_pair(arg, 1));

    e  = 1;
    s  = 1;
    nu = 1;
    nd = 1;

    for(int i=0; i<v.size(); ++i)
        e*=v[i].second+1;
    for(int i=0; i<v.size(); ++i)
        nu=mod(nu*(expow(v[i].first, v[i].second+1)-1),MOD);
    for(int i=0; i<v.size(); ++i)
        nd=mod(nd*(v[i].first-1), MOD);

    s = mod(nu*expow(nd, MOD-2),MOD);

    fprintf(fo,"%lld %lld\n",e,s);
}

int main(void) {
    fi = fopen("ssnd.in", "r");
    fo = fopen("ssnd.out", "w");
    int t;
    i64 q;

    erat(1001000);

    fscanf(fi,"%d",&t);
    for(int i=0; i<t; ++i) {
        fscanf(fi,"%lld",&q);
        query(q);
    }

    fclose(fi);
    fclose(fo);
    return 0;
}