# include <stdio.h>
# include <string.h>
# define MAXN 150
# define BAZA 10
# define NRCFB 1
# define DEBUG
typedef struct NUMAR{
long int len,v[MAXN+1];
}NUMAR;
NUMAR nrp,sol,unu;
long int sole;
long int nrcf(long int a)
{
long int sol=0;
do{
sol++;
a/=10;
}while (a);
return sol;
}
void scrie_numar(FILE *g, NUMAR& a)
{
long int i,j;
fprintf(g,"%ld",a.v[a.len]);
for (i=a.len-1;i>=1;i--)
{
for (j=nrcf(a.v[i])+1;j<=NRCFB;j++) fprintf(g,"0");
fprintf(g,"%ld",a.v[i]);
}
fprintf(g,"\n");
}
void normalizeaza_adunare(NUMAR& a)
{
long int i;
for (i=1;i<=a.len-1;i++)
{
a.v[i+1]+=a.v[i]/BAZA;
a.v[i]%=BAZA;
}
while (a.v[a.len]>=BAZA)
{
a.v[a.len+1]=a.v[a.len]/BAZA;
a.v[a.len]%=BAZA;
a.len++;
}
}
void aduna(NUMAR &dest, NUMAR &a, NUMAR& b)
{
long int i,min,max;
min = a.len<b.len ? a.len : b.len;
max = a.len>b.len ? a.len : b.len;
for (i=1;i<=min;i++) dest.v[i]=a.v[i]+b.v[i];
for (i=min+1;i<=a.len;i++) dest.v[i]=a.v[i];
for (i=min+1;i<=b.len;i++) dest.v[i]=b.v[i];
dest.len=max;
normalizeaza_adunare(dest);
}
void inmulteste(NUMAR& dest, NUMAR& a, NUMAR& b)
{
long int i,j;
dest.len=a.len+b.len-1;
for (i=1;i<=dest.len;i++)
dest.v[i]=0;
for (i=1;i<=a.len;i++)
for (j=1;j<=b.len;j++)
dest.v[i+j-1]+=a.v[i]*b.v[j];
normalizeaza_adunare(dest);
}
void imparte_la_nr(NUMAR& a, int div)
{
long int remainder = 0, i;
for (i=a.len;i>=1;i--)
{
remainder = remainder*BAZA + a.v[i];
a.v[i] = remainder/div;
remainder = remainder%div;
}
while (a.v[a.len]==0 && a.len>1)
a.len--;
//scrie_numar(stdout,a);
}
void normalizeaza_scadere(NUMAR& a)
{
long int i;
for (i=1;i<=a.len-1;i++)
while (a.v[i]<0)
{
a.v[i]+=BAZA;
a.v[i+1]--;
}
while (a.v[a.len]==0 && a.len>1)
a.len--;
}
void scade_numar(NUMAR& a, int scad)
{
a.v[1]-=scad;
//printf("Inainte de scadere\n");
//scrie_numar(stdout,a);
normalizeaza_scadere(a);
}
void aduna_numar(NUMAR& a, int adun)
{
a.v[1]+=adun;
normalizeaza_adunare(a);
}
void make_1(NUMAR& a)
{
a.len = 1;
a.v[1] = 1;
}
void make_0(NUMAR &a)
{
a.len = 1;
a.v[1] = 0;
}
int compara(NUMAR& a, NUMAR &b)
{
long int i;
if (a.len<b.len) return -1;
if (a.len>b.len) return 1;
for (i=a.len;i>=1;i--)
{
if (a.v[i]<b.v[i]) return -1;
if (a.v[i]>b.v[i]) return 1;
}
return 0;
}
void scrie(NUMAR &baza, long int exponent)
{
FILE *g=fopen("numere2.out","w");
scrie_numar(g,baza);
fprintf(g,"%ld\n",exponent);
fclose(g);
}
void citire(NUMAR& a)
{
char buffer[120];
FILE *f=fopen("numere2.in","r");
fscanf(f,"%s",buffer+1);
fclose(f);
char c;
a.len=0;
long int dig,i,n=strlen(buffer+1);
for (i=1;i<=n/2;i++)
{
c=buffer[i];
buffer[i]=buffer[n-i+1];
buffer[n-i+1]=c;
}
char *p=buffer;
do{
a.len++;
a.v[a.len]=0;
for (i=1,dig=1;i<=NRCFB && p[i];i++,dig*=10)
a.v[a.len]+=(p[i]-'0')*dig;
if (p[i]) p+=NRCFB;
else break;
} while (1);
}
void ridica_la_putere(NUMAR a, long int exp, NUMAR &sol)
{
if (exp==0)
{
sol = unu;
return;
}
NUMAR half,tempsol;
ridica_la_putere(a,exp/2,half);
inmulteste(tempsol,half,half);
if (exp%2==1)
{
inmulteste(sol,tempsol,a);
}
else
{
sol=tempsol;
}
}
long int nrcifre(NUMAR& n, long int exp)
{
return (n.len-1)*exp;
}
NUMAR searchbin(NUMAR& li, NUMAR& lf, long int exp, NUMAR& newlf)
{
NUMAR m,power;
int comparatie;
while (compara(li,lf) == -1)
{
aduna(m,li,lf);
imparte_la_nr(m,2);
//TODO
// printf("\n");
// printf(" LI: ");scrie_numar(stdout,li);
// printf(" LF: ");scrie_numar(stdout,lf);
// printf(" M : ");scrie_numar(stdout,m);
// getchar();
//debug!
//verifica intai grosier daca m^exp are mai multe cifre decat nrp
if (nrcifre(m,exp)>nrp.len)
{
// printf("GO LEFT FAST\n");
lf = m;
scade_numar(lf,1);
continue;
}
ridica_la_putere(m,exp,power);
comparatie = compara(power,nrp);
if (comparatie == 0)
{
newlf=m;
return m;
}
if (comparatie == -1)
{
// printf("GO RIGHT\n");
li = m;
aduna_numar(li,1);
}
if (comparatie == 1)
{
// printf("GO LEFT\n");
lf = m;
scade_numar(lf,1);
}
}
if (compara(li,lf)==0)
{
m=li;
ridica_la_putere(m,exp,power);
comparatie = compara(power,nrp);
if (comparatie == 0)
{
newlf=m;
return m;
}
}
newlf = lf;
m.len = -1;
return m;
}
void calculeaza()
{
sol=nrp;
sole=1;
NUMAR solloc,li,lf,newlf;
solloc.len = -1;
make_1(unu);
long int i;
lf = sol;
for (i=2;i<=332;i++)
{
//printf("Acum cautam o solutie binara pentru exponentul %ld --- ",i);
li = unu;
solloc = searchbin(li,lf,i,newlf); //cautam binar un numar care ridicat la puterea i sa dea tocmai nrp
lf = newlf;
if (solloc.len != -1)
{
sol = solloc;
sole = i;
}
/*if (solloc.len != -1)
printf("Exista!\n");
else
printf("Wrong again :-<\n");
*/
}
}
int main()
{
citire(nrp);
calculeaza();
scrie(sol,sole);
return 0;
}