Cod sursa(job #1740175)

Utilizator sulzandreiandrei sulzandrei Data 11 august 2016 02:52:55
Problema Suma si numarul divizorilor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 4.51 kb
//http://www.infoarena.ro/problema/ssnd
#include <fstream>
#include <bitset>
#include <iostream>
#include <vector>
#define ull unsigned long long int
using namespace std;
ifstream in("ssnd.in");
ofstream out("ssnd.out");
#define mod 9973
#define pb push_back
bitset<1000003> v;
vector< ull > primes;
void sieve()
{
    primes.pb(2);
    for(ull i = 3 ; i*i <= 1000000; i +=2)
        if(v[i] == 0)
        for(ull j = i*i ; j<= 1000000 ; j += 2*i )
            v[j] = 1;
    for(ull i = 3 ; i <= 1000000 ; i+=2)
        if(v[i] == 0)
            primes.pb(i);
}
void solve(ull n)
{
    ull d = 1,s = 0;
    //cout<<"n = "<<n<<"are divizorii primi:";
    for(const auto& prime :primes)
        if(prime <=n && n%prime == 0)
        {
            ull div = prime;
            ull nr = 1;
            while(n % prime == 0)
            {
                div *= prime;
                n /= prime;
                nr++;
            }
            //cout << prime <<" ";
            d *= nr;
            div = (div-1)/(prime-1);
            if(s == 0)
                s = div;
            else
                s *= div;
        }
    if(n>1)
    {
        s = n+1;
        d = 2;
    }
    out << d << " " << s << '\n';

}
int main()
{
    int t;
    sieve();
    ull n;
    in >> t;
    for( ; t >= 1 ; t--)
    {
        in >> n;
        solve(n);
    }
}


























/*#include <iostream>
#include <fstream>
#include <bitset>
using namespace std;
ifstream in("ssnd.in");
ofstream out("ssnd.out");
#define dim 1000002 // dim>=radical(n) pt. orice n<=10^12
#define mod 9973
#define ull unsigned long long int
bitset<dim> v;
ull n,i,j,t,Ndiv,Sdiv,tes,dp=1,p,d;  //Ndiv=nr. divizorilor; Sdiv= suma divizorilor; tes=nr. de teste; dp = nr. de nr. prime<=dim
ull divp[dim];
void Sieve()
{
    divp[0]=2; // Introducem primu nr. prim separat ca sa nu le mai luam pe cele pare in calcul cand stergem multiplii(Erathostenes);
    for(i=3;i<dim;i+=2)
        if(v[i]==0)//Daca am dat peste un nr. prim atunci il bagam in vectorul divp care retine nr. prime<=dim;
        {
            divp[dp++]=i;
            for(j=i*i;j<dim;j+=2*i)    //Stergem multipli lui i care n-au fost stergi si sarim peste nr. pare evident incepand de
                v[j]=1; //la i*i(ca deja au fost stersi multiplii lui i de la i pana la i*i fiind multiplii altor numere prime mai mici ca i)
        }
}
void calcul()
{
    Sdiv = Ndiv = 1;
    for(i=0;i<dp && divp[i]*divp[i]<=n;i++)//Cat timp nu am luat toate numerele prime care pot fi divizori ai lui n( in cazu in care n e prim o sai verificam pe
    //toti) si al i+1 nr prim la patrat<=n(adica n nu e un nr prim dupa ce am sters divizorul pi (adica stergem  pi^di din produsul lui n sub forma
    //de factori primi), daca divp[i]*divp[i]>n atunci ori n a devenit 1 ori n a devenit un divizor prim la puterea 1(de la mama natura))
        if ((n%divp[i]==0))
        {
            d = 1;
            p = divp[i];
            while(n%divp[i]==0)//cat timp puterea la care apare al i divizor prim in descompunerea lui n in div. primi este>0 atunci stergem cate 1
            {
                n /=divp[i];  //stergem o puterea a unui divizor prim al lui n
                d++;//marim cu 1 puterea la care apare
                p *=divp[i];//calculam pi^(di+1)
            }
        //Deoarece n se scrie ca (p1^d1 * p2^d2*..* pk^dk) si daca a,b numere natural nenule si a^b e intrun interval atunci b e si el in acel interval=>
        //=> nu vom avea depasire si deci nu este necesar sa facem nimic modul mod
            Ndiv *=d; //Ndiv trebuie sa arate la sfarsit sub forma (d1+1)*(d2+1)*...*(dk+1)
            Sdiv *=(p-1)/(divp[i]-1)%mod;//p va fi (pi^(di+1)-1)/(pi-1) si vrem ca Sdiv sa fie sub forma (p1^(d1+1)-1)/(p1-1)*...*(pk^(dk+1)-1)/(pk-1)
        }
    //Aceasta intructiune este foarte importanta deoarece acopera 2 cazuri pt n fiind un nr. prim :cazu 1  cand n e numaru prim de la inceput;
    //cazu2: cand cel mai mare divizor prim al lui n apare la puterea 1 si pt ambele cazuri di+1 va fi egal 2 si (pi^(di+1)-1)/(pi-1)=(n^2-1)/(n-1)
    if(n>1)
    {
        Sdiv *= (n*n-1)/(n-1)%mod;
        Ndiv *=2;
    }
    out<<Ndiv<<" "<<Sdiv%mod<<"\n";
}
int main()
{
    in>>t;
    Sieve();
    //Acum avem in divp toate numerele prime <=dim si doar verificam care dintre aceste nr prime sunt divizori ai lui n
    for(tes=0;tes<t;tes++)
    {
        in>>n;
        calcul();//Aici se petrece magia ;)
    }
}
*/