Cod sursa(job #2216588)

Utilizator Dobricean_IoanDobricean Ionut Dobricean_Ioan Data 27 iunie 2018 13:58:54
Problema Numere 2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.39 kb
#include <fstream>
#include <cstring>
#include <iostream>

using namespace std;

ifstream fin ("numere2.in");
ofstream fout ("numere2.out");

const int Dim = 155;

class Big{
    enum { MAX = 20000 };
    short x[MAX];
    int n;
public:
    Big(int nr = 0);
    short& operator [] (int i) { return x[i]; }
    friend Big operator * (Big A, int B);
    friend Big operator * (Big A, Big B);
    friend Big operator + (Big o1, Big o2);
    friend Big operator / ( Big o1, int x);
    friend Big operator - ( Big o1, Big o2);
    friend ostream& operator << (ostream& os, const Big& ob);
	friend istream& operator >> ( istream& is, Big& ob);
	bool operator <= (const Big & B)  const {
		if ( n < B.n)
			return true;
		if ( n > B.n)
			return false;
		for ( int i = n; i >= 1; --i) {
			if ( x[i] < B.x[i] )
				return true;
			if ( x[i] > B.x[i] )
				return false;
			}
		return true;
	}
	bool operator == ( const Big & ob ) const {
		if ( n != ob.n)
			return false;
		for ( int i = 1; i <= n; ++i)
			if ( ob.x[i] != x[i] )
				return false;
		return true;
	}
};

Big a,p,sol;
int b; 
bool BinarySearch(int b);
 Big Pow(Big x, int n);
 
int main() {
	
	fin >> p;
	bool ok = false;
	for ( int power = Dim; power >= 2; --power)
	if ( BinarySearch(power) ) {
			fout << sol << "\n" << power;
			ok = true;
			break;
			}
	if( !ok )
		fout << p << "\n" << 1 << "\n";
}
	


bool BinarySearch(int b) {
	
	Big st = 1, dr = p,mj;

	while ( st <= dr ) {
		mj = ( st + dr ) / 2;
			
		Big P =  Pow(mj,b);
		if ( P == p) {
			sol = mj;
			return true;
		}
		else
			if ( P <= p )
				st = mj + (Big)1;
		else
			dr = mj - (Big)1;
	}
	return false;
	
}

Big Pow(Big x, int n) {
	
		 if ( n == 0 ) return 1;
		Big res = Pow(x, n / 2);
        res = ( res * res) ;
        if ( n % 2 == 1 )
            res = (res * x) ;
        return res;
}

istream& operator >> ( istream& is,  Big& ob) {
	
	char x[201];
	is.getline(x,201);
	ob.n = strlen(x);
	for ( int i = strlen(x); i >= 1; --i)
		ob.x[i] = x[strlen(x) - i] - '0';
	return is;
}
ostream& operator << (ostream& os, const Big& ob)
{
    for ( int i = ob.n; i >= 1; --i )
        os << ob.x[i];
    return os;
}
 
Big operator + (Big a, Big b)
{
    Big c; int i, t = 0;
    for (i = 1; i <= a.n or i <= b.n or t; ++i, t /= 10)
        c[i] = (t += a[i] + b[i]) % 10;
    c.n = i - 1;
    return c;
}

Big operator * (Big A, Big B) {
	int t=0;
	Big C;
  C.n=A.n+B.n - 1;
  for (int i = 1;i <= A.n + B.n;) C[++i] = 0;
  for (int i = 1;i <= A.n; ++i)
    for (int j = 1;j <= B.n; ++j)
      C.x[ i + j - 1] += A.x[i] * B.x[j];
  for (int i = 1; i <= C.n; ++i)
    { t = ( C.x[i] += t) / 10;
      C.x[i] %= 10;
    }
  if (t) C.x[++C.n]=t;
  return C;
}
Big operator - (Big a, Big b) {
	int  t = 0;
	Big A = a;
  for ( int i = b.n + 1; i <= A[0]; ++i) b.x[i]=0;
  for ( int i = 1;i <= A.n; ++i)
    A.x[i] +=  ( t = (A.x[i]-=b.x[i] + t) < 0 ) ? 10 : 0;
  while (!A[A.n]) A.n--;
  return A;
}

 
Big operator * (Big a, int b)
{
    Big c; int i, t = 0;
    if ( b == 0 ) return c;
    for (i = 1; i <= a.n or t; ++i, t /= 10)
        c[i] = (t += a[i] * b) % 10;
    c.n = i - 1;
    return c;
}
Big operator /(Big o1, int x) { 
  Big C;
  int R = 0;
  C.n= o1.n;
  for ( int i = o1.n; i >= 1 ; --i)
    { C[i] = (R = 10 * R+o1.x[i]) / x;
      R %= x;
    }
  while (!C.x[C.n] and C.n>1) --C.n;
  return C;
}
 
Big::Big(int nr) {
    memset(x, 0, sizeof(x)); n = 0;
    while ( nr ) {
        x[++n] = nr % 10; nr /= 10;
    }
}