Cod sursa(job #1554100)

Utilizator TimitocArdelean Andrei Timotei Timitoc Data 20 decembrie 2015 21:47:37
Problema Numere 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.02 kb
#include <iostream>
#include <cstdio>
#include <cstring>
#define MAXN 215
#define MAXP 200

using namespace std;

typedef int huge[MAXN];

void atrib(huge nr, char c[MAXN])
{
    nr[0] = 0;
    for (int i = strlen(c)-1; i+1; --i)
        nr[++nr[0]] = c[i]-'0';
}

void atrib(huge nr, int x)
{
    nr[0] = 0;
    while (x)
        nr[++nr[0]] = x%10, x/=10;
}

void atrib(huge a, huge b)
{
    for (int i = 0; i <= b[0]; i++)
        a[i] = b[i];
}
/// returns -1(a<b), 0 (a==b), 1(a>b)
int cmp(huge a, huge b)
{
    if (a[0] != b[0]) return a[0] < b[0] ? -1 : 1;
    for (int i = a[0]; i; --i)
        if (a[i] < b[i])
            return -1;
        else if (a[i] > b[i])
            return 1;
    return 0;
}

void sum(huge a, huge b, huge c)
{
    int r = 0;
    for (int i = a[0]+1; i <= b[0]; i++) a[i] = 0;
    for (int i = b[0]+1; i <= a[0]; i++) b[i] = 0;
    c[0] = max(a[0], b[0]);
    for (int i = 1; i <= c[0]; i++) {
        c[i] = (r += a[i]+b[i])%10;
        r /= 10;
    }
    while (r)
        c[++c[0]] = r%10, r/=10;
}

void mult(huge a, huge b, huge c)
{
    int T = 0;
    c[0] = a[0]+b[0]-1;
    for (int i = 1; i <= c[0]; i++) c[i] = 0;
    for (int i = 1; i <= a[0]; i++)
        for (int j = 1; j <= b[0]; j++)
            c[i+j-1] += a[i]*b[j];
    for (int i = 1; i <= c[0]; i++) {
        c[i] = (T+=c[i])%10;
        T /= 10;
    }
    while (T)
        c[++c[0]] = T%10, T /= 10;

}
/// returns division reminder of [a/b]
int div(huge a, int b, huge c)
{
    int T = 0;
    c[0] = a[0];
    for (int i = a[0]; i; --i)
    {
        T = T*10 + a[i];
        c[i] = T/b;
        T %= b;
    }
    while (c[0]>1 && !c[c[0]]) c[0]--;
}
/// rise a to power b, saved in c
/// returns 1 if successful, 0 otherwise
int pwr(huge a, int b, huge c)
{
    if (a[0]*b >= MAXN-20)
        return 0;
    huge aux;
    atrib(c, a);
    for (int i = 1; i < b; i++)
    {
        mult(c, a, aux);
        atrib(c, aux);
    }
    return 1;
}

void print(huge a)
{
    for (int i = a[0]; i; --i)
        printf("%d", a[i]);
}

char s[MAXN];
huge p;

void solve()
{
    huge lo, hi, mid, aux;
    int ok;
    for (int power = MAXP; power; --power) {
        atrib(lo, 2);
        atrib(hi, p);
        ok = 0;
        /// caut binar baza
        while (!ok && cmp(lo, hi) <= 0)
        {
            sum(lo, hi, mid);
            div(mid, 2, aux);
            atrib(mid, aux);
            int k;
            if (pwr(mid, power, aux))
                k = cmp(aux, p);
            else
                k = 1;
            if (k == 0)
                ok = 1;
            else if (k == -1) {
                atrib(aux, 1);
                sum(mid, aux, lo);
            }
            else {
                atrib(hi, mid);
                if (cmp(lo, hi) == 0)
                    break;
            }
        }
        if (ok == 1) {
            print(mid);
            printf("\n%d", power);
            break;
        }
    }
}

int main()
{
    freopen("numere2.in", "r", stdin);
    freopen("numere2.out", "w", stdout);

    gets(s);
    atrib(p, s);
    solve();

    return 0;
}