Cod sursa(job #708305)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 6 martie 2012 18:11:29
Problema Numere 2 Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.44 kb
#include <fstream>
#include <cstring>

#define CMax 1005
#define Base 10000

using namespace std;

class Huge
{
	public: int n[CMax];
	Huge ()
	{
		memset (n, 0, sizeof (n));
	}

    void operator = (Huge A)
	{
		memcpy (n, A.n, sizeof (A.n));
	}

	void operator = (int A)
	{
		memset (n, 0, sizeof (n));
		for (; A>0; A/=Base) n[++n[0]]=A%Base;
	}

	Huge operator + (Huge A) const
	{
		Huge B; int i, T=0;
		for (i=1; i<=A.n[0] or i<=n[0] or T; ++i, T/=Base)
		{
			B.n[i]=(T+=(A.n[i]+n[i]))%Base;
		}
		B.n[0]=i-1;
		return B;
	}

	Huge operator - (int A) const
	{
		Huge B; int i, T=A;
		memcpy (B.n, n, sizeof (n));
        for (i=1; T; ++i, T/=Base)
        {
            B.n[i]-=(T%Base);
            if (B.n[i]<0) --B.n[i+1], B.n[i]+=Base;
        }
        for (; B.n[0]>1 and !B.n[B.n[0]]; --B.n[0]);
        return B;
	}

	Huge operator * (Huge A) const
	{
		Huge C;	int i, j, T;
		for (i=1; i<=n[0]; ++i)
		{
			for (T=0, j=1; j<=A.n[0] or T; ++j, T/=Base)
			{
				C.n[i+j-1]=(T+=(C.n[i+j-1]+n[i]*A.n[j]))%Base;
			}
			if (i+j-2>C.n[0]) C.n[0]=i+j-2;
		}
		return C;
	}

	Huge operator / (int B) const
	{
		Huge A; memcpy (A.n, n, sizeof (n));
		int i, T=0;
		for (i=A.n[0]; i>0; --i, T%=B)
		{
			A.n[i]=(T=T*Base+A.n[i])/B;
		}
		for (; A.n[0]>1 and !A.n[A.n[0]]; --A.n[0]);
		return A;
	}

	bool operator < (Huge A) const
	{
	    if (n[0]<A.n[0]) return true;
	    if (n[0]>A.n[0]) return false;
	    for (int i=n[0]; i>0; --i)
	    {
	        if (n[i]<A.n[i]) return true;
	        if (n[i]>A.n[i]) return false;
	    }
	    return false;
	}

	bool operator == (Huge A) const
	{
	    if (n[0]!=A.n[0]) return false;
	    for (int i=1; i<=n[0]; ++i)
	    {
	        if (n[i]!=A.n[i]) return false;
	    }
	    return true;
	}

	friend ifstream& operator >> (ifstream &f, Huge &A)
	{
	    char Number[CMax]; memset (Number, 0, sizeof (0));
	    f >> Number; int L=strlen (Number);
	    for (int i=L-1; i>=0; i-=4)
	    {
	        A.n[++A.n[0]]=Number[i]-'0';
	        if (i>0) A.n[A.n[0]]+=((Number[i-1]-'0')*10);
	        if (i>1) A.n[A.n[0]]+=((Number[i-2]-'0')*100);
	        if (i>2) A.n[A.n[0]]+=((Number[i-3]-'0')*1000);
	    }
	    return f;
	}

	friend ofstream& operator << (ofstream &f, Huge &A)
	{
		f<< A.n[A.n[0]];
		for (int i=A.n[0]-1; i>0; --i)
		{
			if (A.n[i]==0)
			{
				for (int X=1; X<Base; X*=10) f << "0";
				continue;
			}
			for (int X=A.n[i]*10; X<Base; X*=10) f << "0";
			f<< A.n[i];
		}
		return f;
	}
};

Huge P, S; int SE;

inline Huge Pow (Huge A, int E)
{
    Huge R; R=1;
    while (E>0)
    {
        if (E&1) R=R*A, --E;
        else A=A*A, E>>=1;
        if (P<A) return A;
        if (P<R) return R;
    }
    return R;
}

inline void BSearch (int E)
{
    Huge L, R, One;
    L=0, R=P, One=1;
    while (L<R or L==R)
    {
        Huge Mid; Mid=(L+R)/2;
        if (Pow (Mid, E)==P)
        {
            S=Mid, SE=E;
            return;
        }
        if (Pow (Mid, E)<P) L=Mid+One;
        else R=Mid-1;
    }
}

void Solve ()
{
    Huge Zero; Zero=0, S=0;
    for (int E=40; E>0; --E)
    {
        BSearch (E);
        if (!(S==Zero)) return;
    }
}

void Read ()
{
    ifstream fin ("numere2.in");
    fin >> P;
}

void Print ()
{
	ofstream fout ("numere2.out");
	fout << S << "\n" << SE << "\n";
}

int main ()
{
    Read ();
    Solve ();
	Print ();
	return 0;
}