Cod sursa(job #1014689)

Utilizator nod_softwareBudisteanu Ionut Alexandru nod_software Data 23 octombrie 2013 00:46:31
Problema Suma si numarul divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 6.67 kb
#include <stdio.h>
#include <fstream>
#include <vector>
#include <math.h>

using namespace std;

const long long _iMaxNumber =  1e12;
const int _iSqrtMaxNumber = 1e6+1;

long long lldNumber;

class TEratosthenesSieve
{
   public:
        std::vector <int> m_vPrimes;

        TEratosthenesSieve(long long lldMaxNumber);
        ~TEratosthenesSieve();

        void PrintPrimes(FILE * fOut);
    protected:
        static const int s_iSieveLength = _iSqrtMaxNumber;
        char m_vSieve[s_iSieveLength];

        virtual void ComputeSieve(long long lldMaxValue);
        virtual void ReorderSieve(int iMaxValue);
    private:
        int InitSieve(int iMaxValue);
};

struct TDivisor
{
    int iFactor, iExponent;
    TDivisor(int iNewFactor, int iNewExponent) {iFactor=iNewFactor; iExponent=iNewExponent;}
};

class TDivisors
{
    public:
        TDivisors(long long lldNumber, int iModulo, TEratosthenesSieve * objSieve);
        ~TDivisors();

        vector <TDivisor> m_vDivisors;

        virtual int ComputeNumberOfDivisors();
        virtual int ComputeSumOfDivisors();
    private:
        int iModulo;
        TEratosthenesSieve * objSieve;

        long long Power_logarithmic(int iBase, int iExponent);
        void ComputeDivisors(long long lldNumbers);
};

//---------------------------------------------------
//------------------TEratosthenesSieve---------------
//---------------------------------------------------
TEratosthenesSieve::TEratosthenesSieve(long long lldMaxNumber)
{
    lldMaxNumber=sqrt(lldMaxNumber);

    this->ComputeSieve(lldMaxNumber);
    this->ReorderSieve(lldMaxNumber);
}
//---------------------------------------------------
void TEratosthenesSieve::PrintPrimes(FILE * fOut)
{
    std::vector <int>::iterator itIndex;

    for (itIndex=this->m_vPrimes.begin(); itIndex!=this->m_vPrimes.end(); ++itIndex)
        fprintf(fOut,"%d ",*itIndex);
}
//---------------------------------------------------
void TEratosthenesSieve::ReorderSieve(int iMaxValue)
{
    for (int iIndex=2; iIndex<=s_iSieveLength; iIndex++)
        if (m_vSieve[iIndex]==0)
            m_vPrimes.push_back(iIndex);
}
//---------------------------------------------------
int TEratosthenesSieve::InitSieve(int iMaxValue)
{
    for (int iIndex=0; iIndex<=iMaxValue; iIndex++)
        m_vSieve[iIndex]=0;

    return 1;
}
//---------------------------------------------------
TEratosthenesSieve::~TEratosthenesSieve()
{
    this->m_vPrimes.clear();
    //delete[] m_vSieve;
}
//---------------------------------------------------
void TEratosthenesSieve::ComputeSieve(long long iMaxValue)
{
    this->InitSieve(iMaxValue);//init Sieve

    int iNumber;
    for (int i=2; i<iMaxValue; i++)
        if (m_vSieve[i]!=1)
        {
            iNumber = i+i;
            while (iNumber <= iMaxValue)
            {
                m_vSieve[iNumber]=1;
                iNumber += i;
            }
        }
}
//---------------------------------------------------
//--------------------TDivisors----------------------
//---------------------------------------------------
TDivisors::TDivisors(long long lldNumber, int iModulo, TEratosthenesSieve * objSieve)
{
    this->iModulo=iModulo;
    this->objSieve=objSieve;

    ComputeDivisors(lldNumber);
}
//---------------------------------------------------
TDivisors::~TDivisors()
{
    this->m_vDivisors.clear();
}
//---------------------------------------------------
void TDivisors::ComputeDivisors(long long lldNumber)
{
    std::vector <int>::iterator itIndex;
    int iSqrtNumber = sqrt(lldNumber), iExponent;

    for (itIndex=this->objSieve->m_vPrimes.begin(); itIndex!=this->objSieve->m_vPrimes.end(); ++itIndex)
    {

        if ((*itIndex>iSqrtNumber)||(lldNumber==1))
            break;

        iExponent=0;

        while (lldNumber % *itIndex == 0)
        {
            lldNumber/=*itIndex;

            iExponent++;
        }
        if (iExponent!=0)
        {
            this->m_vDivisors.push_back(TDivisor(*itIndex,iExponent));
            iSqrtNumber = sqrt(lldNumber);
        }
    }

    if (lldNumber!=1)
    {
        this->m_vDivisors.push_back(TDivisor(lldNumber,1));
    }

}
//---------------------------------------------------
long long TDivisors::Power_logarithmic(int iBase, int iExponent)
{
    if (iExponent==1) return (iBase);
   else
   {
       long long iHalf=Power_logarithmic(iBase, int(iExponent/2));

       if (iExponent%2==0) return (iHalf*iHalf);
       else return (((iHalf*iHalf))*(iBase));

   }

/*   if (iExponent==1) return (iBase % this->iModulo); else
   {
       int iHalf=Power_logarithmic(iBase, int(iExponent/2));
       iHalf%=this->iModulo;

       if (iExponent%2==0) return (iHalf*iHalf) % this->iModulo;
       else return (((iHalf*iHalf) % this->iModulo)*(iBase % this->iModulo))%this->iModulo;
   }*/
}
//---------------------------------------------------
int TDivisors::ComputeNumberOfDivisors()
{
    std::vector <TDivisor>::iterator itIndex;
    int iValue=1;

    for (itIndex=this->m_vDivisors.begin(); itIndex!=this->m_vDivisors.end(); ++itIndex)
        iValue *= (itIndex->iExponent+1);

    return iValue;
}
//---------------------------------------------------
int TDivisors::ComputeSumOfDivisors()
{
    std::vector <TDivisor>::iterator itIndex;
    long long iValue=1;

    for (itIndex=this->m_vDivisors.begin(); itIndex!=this->m_vDivisors.end(); ++itIndex)
    {
        iValue *= (Power_logarithmic(itIndex->iFactor,itIndex->iExponent+1)-1);
        iValue /= (itIndex->iFactor-1);
        iValue %= this->iModulo;
    }

    return iValue;
}
//---------------------------------------------------
//---------------------------------------------------
//---------------------------------------------------
void ReadData(FILE * fOut, TEratosthenesSieve* objSieve)
{
    ifstream fin ("ssnd.in");

    int iCount;

    fin>>iCount;

    for (int iIndex=0; iIndex<iCount; iIndex++)
    {
        //fscanf(fIn,"%lld",&lldNumber);
        fin>>lldNumber;

        TDivisors * objDivisors = new TDivisors(lldNumber,9973,objSieve);

        fprintf(fOut,"%d ",objDivisors->ComputeNumberOfDivisors());
        fprintf(fOut,"%d",objDivisors->ComputeSumOfDivisors());


        fprintf(fOut,"\n");
        objDivisors->~TDivisors();
    }

}
//---------------------------------------------------
int main()
{
    TEratosthenesSieve* objSieve = new TEratosthenesSieve(1e12);

    FILE * fOut = fopen("ssnd.out","w");

    //objSieve->PrintPrimes(fOut);
    ReadData(fOut, objSieve);

    fclose(fOut);

    objSieve->~TEratosthenesSieve();

    return 0;
}