Pagini recente » Cod sursa (job #148285) | Cod sursa (job #1014689)
#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;
}