Cod sursa(job #2334080)

Utilizator Mathe13Mathe Andrei Mathe13 Data 2 februarie 2019 11:00:50
Problema Al k-lea termen Fibonacci Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.44 kb
#include <iostream>
#include <fstream>

using namespace std;

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

namespace QuikMath {
    int poppow(int x, int y) {
        int result = 1;
        for (int i = 1; i <= y; ++i)
            result *= x;
        return result;
    }

    int faktorial(int x, int y) {
        int result = 1;
        for (int i = x; i <= y; ++i)
            result *= i;
        return result;
    }

    void copy_array(long long x[], long long y[], long long length) {
        for (long long i = 0; i <= length; ++i)
            x[i] = y[i];
    }

    void clear_array(long long x[], long long length) {
        for (int i = 0; i <= length; ++i)
            x[i] = 0;
    }


    /// BIGBOIS
    void bigbois_init(long long x, long long result[]) {
        while (x) {
            result[++result[0]] = x%10;
            x /= 10;
        }
    }

    void bigbois_sum(long long x[], long long y[], long long z[]) {
        long long rest = 0, length;
        length = max(x[0], y[0]);
        for (long long i = 1; i <= length; ++i) {
            rest += x[i] + y[i];
            z[i] = rest%10;
            ++z[0];
        }
        if (rest)
            z[++z[0]] = rest;
    }

    void bigbois_sub(long long x[], long long y[], long long z[]) {
        long long loan;
        z[0] = x[0];
        for (long long i = 1; i <= x[0]; ++i)
            if (x[i] >= y[i])
                z[i] = x[i] - y[i];
            else {
                loan = i + 1;
                while (x[loan] == 0)
                    x[loan++] = 9;
                --x[loan];
                x[i] = 10 + x[i] - y[i];
            }
        for (long long i = z[0]; i > 0; --i)
            if (z[i] == 0)
                --z[0];
    }

    void bigbois_mul(long long x[], long long y[], long long z[]) {
        long long rest = 0;
        z[0] = x[0] + y[0] - 1;
        for (long long i = 1; i <= x[0]; ++i)
            for (long long j = 1; j <= y[0]; ++j)
                z[i+j-1] += x[i] * y[j];
        for (long long i = 1; i <= z[0]; ++i){
            rest += z[i];
            z[i] = rest%10;
            rest /= 10;
        }
        if (rest)
            z[++z[0]] = rest;
    }

    void bigbois_poppow(long long x, long long y, long long res[]) {
        long long result[60000];
        long long aux[60000]; aux[0] = 0;
        bigbois_init(x, aux);
        for (long long i = 1; i <= y; ++i){
            bigbois_mul(res, aux, result);
            copy_array(res, result, result[0]);
            clear_array(result, result[0]);
        }
    }

    void bigbois_faktorial(long long x, long long y, long long res[]) {
        long long result[60000];
        for (long long i = x; i <= y; ++i) {
            long long aux[60000]; aux[0] = 0;
            bigbois_init(i, aux);
            bigbois_mul(res, aux, result);
            copy_array(res, result, result[0]);
            clear_array(result, result[0]);
        }
    }
};

long long n;
long long A[60000], B[60000], C[60000];

void Solve()
{
    // n!*2^(n*n)
    A[0] = A[1] = 1;
    B[0] = B[1] = 1;
    QuikMath::bigbois_faktorial(1, n, A);
    QuikMath::bigbois_poppow(2, n*n, B);
    QuikMath::bigbois_mul(A, B, C);
}

void Read()
{
	fin >> n;
}

void Write()
{
	for (long long i = C[0]; i > 0; --i)
		fout << C[i];
}

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