Cod sursa(job #2159105)

Utilizator Mihai_PredaPreda Mihai Dragos Mihai_Preda Data 10 martie 2018 19:08:30
Problema Rsir Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.01 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <bitset>
#include <set>

using namespace std;

long long t0, t1, a, b, x, y, z;
long long m, n;

long long GetNext()
{
    long long ret = (a * t0 * t0 + b * t1 * t1 + x * t0 + y * t1 + z) % m;
    t0 = t1;
    t1 = ret;
    return ret;
}

bitset<7005> ap[3505];

void ClearAp()
{
    for(long long i = 0; i < 3505; ++i)
        for(int j = 0; j < 7005; ++j)
            ap[i][j] = 0;
}

int main()
{

    ifstream in("rsir.in");
    ofstream out("rsir.out");
    in >> t0 >> t1 >> a >> b >> x >> y >> z;
    in >> m >> n;
    t0 %= m, t1 %= m;
    long long copyT0 = t0, copyT1 = t1;
    in.close();
    if(n < 5e7)
    {
        if(n == 0)
            out << t0;
        else if(n == 1)
            out << t1;
        else
        {
            long long rasp;
            for(long long i = 2; i <= n; ++i)
                rasp = GetNext();
            out << rasp;
        }
        return 0;
    }
    ClearAp();
    long long startPeriod[2];
    long long periodPos = -1;

    if(t0 < 3505)
        ap[t0][t1] = 1;
    long long ind = 2, current = t1, last;
    for(long long i = 0; i < m * m; ++i)
    {
        last = current; //v[ind-1] = last
        current = GetNext(); //v[ind] = current;

        if(last < 3505)
        {
            if(ap[last][current])
            {
                startPeriod[0] = last;
                startPeriod[1] = current;
                periodPos = ind;
                break;
            }
            ap[last][current] = true;
        }
        ind++;
    }

    if(periodPos == -1)
    {
        ClearAp();
        ind = 2, current = t1, last;
        for(long long i = 0; i < m * m; ++i)
        {
            last = current; //v[ind-1] = last
            current = GetNext(); //v[ind] = current;

            if(last >= 3505)
            {
                if(ap[last-3505][current])
                {
                    startPeriod[0] = last;
                    startPeriod[1] = current;
                    periodPos = ind;
                    break;
                }
                ap[last-3505][current] = true;
            }
            ind++;
        }
    }

    long long first;
    t0 = copyT0, t1 = copyT1;
    if(t0 == startPeriod[0] && t1 == startPeriod[1])
        first = 1;
    else
    {
        current = t1;
        ind = 2;
        while(true)
        {
            last = current;
            current = GetNext();
            if(last == startPeriod[0] && current == startPeriod[1])
            {
                first = ind;
                break;
            }
            ind++;
        }
    }

    long long periodSize = periodPos - first;
    long long remain = (n - first + 1) % periodSize;
    if(remain == 0)
        remain = periodSize - 1;
    else
        remain--;
    long long rasp = current;
    while(remain--)
        rasp = GetNext();

    out << rasp;
    out.close();
    return 0;
}