Cod sursa(job #2836961)

Utilizator Stefan_DomuncoStefan Domunco Stefan_Domunco Data 21 ianuarie 2022 12:01:26
Problema Atac Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.41 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 32e3 + 5, MMAX = 5e5 + 4;

int A, B, C, D, x, y;
int n, q, p, depth[NMAX];
int peuler[2 * NMAX + 5], nrpeuler = 0;
int rmq[2 * NMAX + 5][22], firstPos[NMAX];
int ans[MMAX];

vector <int> g[NMAX];
map < pair <int, int>, int > costMuchii;
bitset <NMAX> viz;

inline void citire()
{
    memset(firstPos, 0, sizeof(firstPos));
    memset(peuler, 0, sizeof(peuler));

    fin >> n >> q >> p;
    for(int i = 2; i <= n; ++i)
    {
        fin >> x >> y;
        costMuchii[{min(x, i), max(x, i)}] = y;
        g[i].push_back(x);
        g[x].push_back(i);
    }

    fin >> x >> y >> A >> B >> C >> D;
}

inline int newX(int X, int Y)
{
    return (X * A + Y * B) % n + 1;
}

inline int newY(int Y, int Z)
{
    return (Y * C + Z * D) % n + 1;
}

void DFS(int node, int dp)
{
    if(firstPos[node] == 0)
        firstPos[node] = nrpeuler + 1;

    if(depth[node] == 0)
        depth[node] = dp;

    viz[node] = 1;
    peuler[++nrpeuler] = node;

    for(auto &it: g[node])
    {
        if(viz[it] == 1)
            continue;

        //peuler[++nrpeuler] = costMuchii[{min(node, it), max(node, it)}];
        DFS(it, dp + 1);
        peuler[++nrpeuler] = node;
    }

    //peuler[++nrpeuler] = costMuchii[aa];
}

void build_rmq()
{
    int i, j;

    for(i = 1; i <= nrpeuler; ++i)
        rmq[i][0] = peuler[i];

    for(j = 1; 1 << j <= nrpeuler; ++j)
    {
        for(i = 1; i + (1 << j) - 1 <= nrpeuler; ++i)
        {
            if(depth[rmq[i][j-1]] < depth[rmq[i + (1 << (j-1))][j-1]])
                rmq[i][j] = rmq[i][j-1];
            else rmq[i][j] = rmq[i + (1 << (j-1))][j-1];
        }

    }
}

inline int solve_query()
{
    int xx, yy;
    xx = x;
    yy = y;

    if(firstPos[xx] > firstPos[yy])
        swap(xx, yy);

    int lung = log2(firstPos[yy] - firstPos[xx] + 1);

    if(depth[rmq[firstPos[xx]][lung]] < depth[rmq[firstPos[yy] - (1 << lung) + 1][lung]])
        return rmq[firstPos[xx]][lung];

    return rmq[firstPos[yy] - (1 << lung) + 1][lung];
}

inline int toLca(int x, int lca)
{
    int i, sol;
    sol = INT_MAX;
    while(x != lca)
    {
        for(auto &it: g[x])
            if(depth[it] < depth[x])
            {
                sol = min(sol, costMuchii[{min(x, it), max(x, it)}]);
                x = it;
                break;
            }
    }

    return sol;
}

int main()
{
    citire();
    costMuchii[{0, 0}] = 0;
    DFS(1, 1);
    build_rmq();

    int xx, yy, i, lca, currentAns, qq = q;
    i = 0;
    while(q)
    {
        --q;
        xx = x;
        yy = y;

        if(x == y)
        {
            ans[++i] = 0;
            x = newX(xx, yy);
            y = newY(yy, ans[i]);
            continue ;
        }

        lca = solve_query();
        currentAns = min(toLca(x, lca), toLca(y, lca));
        ans[++i] = currentAns;

        x = newX(xx, yy);
        y = newY(yy, ans[i]);
    }

    for(i = qq - p + 1; i <= qq; ++i)
        fout << ans[i] << '\n';

//    for(int j = 0; 1 << j <= nrpeuler; ++j)
//    {
//        for(int i = 1; i + (1 << j) - 1 <= nrpeuler; ++i)
//            fout << rmq[i][j] << ' ';
//        fout << '\n';
//    }

//    for(int i = 1; i <= nrpeuler; ++i)
//        fout << peuler[i] << ' ';

    return 0;
}