Cod sursa(job #2050748)

Utilizator Coroian_DavidCoroian David Coroian_David Data 28 octombrie 2017 11:13:35
Problema Atac Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.24 kb
#include <bits/stdc++.h>

#define MAX_N 32000

#define MAX_LOG 15

using namespace std;

FILE *f, *g;

int n, m, pp;

int edg;
int lst[MAX_N + 1];
int urm[MAX_N * 2 + 1];
int nod[MAX_N * 2 + 1];
int cost[MAX_N * 2 + 1];

void add(int a, int b, int c)
{
    edg ++;

    nod[edg] = b;
    cost[edg] = c;
    urm[edg] = lst[a];

    lst[a] = edg;
}

int k;

int first[MAX_N + 1];
int nodul[MAX_N * 2 + 1];

int dep[MAX_N + 1];

unsigned short rmq[MAX_N * 2 + 1][MAX_LOG + 1];
unsigned short poz[MAX_N * 2 + 1][MAX_LOG + 1];

int way[MAX_N + 1][MAX_LOG + 1];
int tata[MAX_N + 1][MAX_LOG + 1];

void readFile()
{
    f = fopen("atac.in", "r");

    fscanf(f, "%d%d%d", &n, &m, &pp);

    int i;
    int a, b;
    for(i = 2; i <= n; i ++)
    {
        fscanf(f, "%d%d", &a, &b);

        add(i, a, b);
        add(a, i, b);
    }
}

int depth;

void dfs(int a, int tatal)
{
    depth ++;

    dep[a] = depth - 1;

    first[a] = k + 1;

    k ++;
    nodul[k] = a;
    rmq[k][0] = depth;
    poz[k][0] = k;

    int p;
    for(p = lst[a]; p != 0; p = urm[p])
    {
        int u = nod[p];

        if(u != tatal)
        {
            tata[u][0] = a;
            way[u][0] = cost[p];

            dfs(u, a);

            k ++;
            nodul[k] = a;
            rmq[k][0] = depth;
            poz[k][0] = k;
        }
    }

    depth --;
}

int lg[MAX_N * 2 + 1];

void getP2()
{
    lg[1] = 0;
    int i;
    for(i = 2; i <= k; i ++)
        lg[i] = lg[i >> 1] + 1;
}

void RMQ()
{
    int i, j;
    int p2, p;

    for(j = 1; j <= MAX_LOG; j ++)
    {
        p2 = (1 << j);
        p = (1 << (j - 1));

        for(i = 1; i + p2 - 1 <= k; i ++)
        {
            if(rmq[i][j - 1] < rmq[i + p][j - 1])
            {
                rmq[i][j] = rmq[i][j - 1];
                poz[i][j] = poz[i][j - 1];
            }

            else
            {
                rmq[i][j] = rmq[i + p][j - 1];
                poz[i][j] = poz[i + p][j - 1];
            }
        }
    }
}

void WAY()
{
    int i, j;
    for(j = 1; j <= MAX_LOG; j ++)
    {
        int p = (1 << j);

        for(i = 1; i <= n; i ++)
        {
            if(dep[i] >= p)
                way[i][j] = min(way[i][j - 1], way[tata[i][j - 1]][j - 1]);
        }
    }
}

void TATA()
{
    int i, j;
    for(j = 1; j <= MAX_LOG; j ++)
    {
        int p = (1 << j);

        for(i = 1; i <= n; i ++)
        {
            if(dep[i] >= p)
                tata[i][j] = tata[tata[i][j - 1]][j - 1];
        }
    }
}

void preCalc()
{
    dfs(1, -1);

    getP2();

    RMQ();

    TATA();

    WAY();
}

int getMin(int st, int dr)
{
    if(st > dr)
        swap(st, dr);

    int len = dr - st + 1;
    int p2 = lg[len];
    int diff = len - (1 << p2);
    int p = 0;

    if(rmq[st][p2] < rmq[st + diff][p2])
        p = poz[st][p2];

    else
        p = poz[st + diff][p2];

    return nodul[p];
}

int getTata(int a, int b)
{
    int i;
    int cr = a;
    for(i = 0; (1 << i) <= b; i ++)
    {
        if(((1 << i) & b) != 0)
            cr = tata[cr][i];
    }

    return cr;
}

int getWay(int i, int len)
{
   // cout << "GET WAY " << i << " " << len << "\n";

    int p2 = lg[len];
    int diff = len - (1 << p2);

  // cout << p2 << " " << diff << " " << way[i][p2] << "\n";

    return min(way[i][p2], way[getTata(i, diff)][p2]);
}

void ansQues()
{
    g = fopen("atac.out", "w");

    int x, y, z;
    int a, b, c, d;
    int nx, ny;

    fscanf(f, "%d%d", &x, &y);
    fscanf(f, "%d%d%d%d", &a, &b, &c, &d);

    while(m > 0)
    {
        z = getMin(first[x], first[y]);
       // cout << "DINTRE " << x << " " << y << " " << z < "\n";
        z = min(getWay(x, dep[x] - dep[z]), getWay(y, dep[y] - dep[z]));

        if(x == y)
            z = 0;

       // cout << "REZ = " << z << "\n";

        if(m <= pp)
            fprintf(g, "%d\n", z);

        nx = (x * a + y * b) % n + 1;
        ny = (y * c + z * d) % n + 1;

        x = nx;
        y = ny;

        m --;
    }

    fclose(f);
    fclose(g);
}

int main()
{
    readFile();

    preCalc();

    ansQues();

    return 0;
}