Cod sursa(job #809665)

Utilizator repp4raduRadu-Andrei Szasz repp4radu Data 8 noiembrie 2012 20:04:12
Problema Atac Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.37 kb
#include <fstream>
#include <vector>

#define MAX 32005
#define LMAX 16
#define INF 0x3f3f3f3f
#define pb push_back
#define mp make_pair
#define f first
#define s second
#define PII pair<int, int>

using namespace std;

vector< PII > v[MAX];
int n, m, p, x, y, X, Y, A, B, C, D, NX, NY, rez;
int dad[LMAX][MAX], minim[LMAX][MAX], lvl[MAX];

void citire()
{
    ifstream in("atac.in");
    in>>n>>m>>p;
    for(int i = 2; i <= n; i++)
    {
        in>>x>>y;
        v[i].pb(mp(x, y));
        v[x].pb(mp(i, y));
    }
    in>>X>>Y>>A>>B>>C>>D;
}

void dfs(int nod, int tata, int nivel, int cost)
{
    lvl[nod] = nivel; dad[0][nod] = tata; minim[0][nod] = cost;
    for(vector< PII > :: iterator it = v[nod].begin(); it != v[nod].end(); it++)
    {
        int dest = (*it).f, c = (*it).s;
        if(dest == tata) continue;
        dfs(dest, nod, nivel + 1, c);
    }
}

void buildAncestors()
{
    minim[0][1] = INF;
    for(int i = 1; i < LMAX; i++)
        for(int nod = 1; nod <= n; nod++)
        {
            int tata = dad[i - 1][nod];
            minim[i][nod] = min(minim[i - 1][nod], minim[i - 1][tata]);
            dad[i][nod] = dad[i - 1][tata];
        }
}

void EqualLevels(int &x, int y)
{
    if(lvl[x] == lvl[y]) return;
    int dif = lvl[x] - lvl[y];
    for(int i = 0; i < LMAX; i++)
        if(dif & (1 << i))
            x = dad[i][x];
}

int getLCA(int x, int y)
{
    if(lvl[x] < lvl[y]) swap(x, y);
    EqualLevels(x, y);
    for(int i = LMAX - 1; i >= 0; i--)
    {
        if(!dad[i][x]) continue;
        if(dad[i][x] == dad[i][y]) continue;
        x = dad[i][x];
        y = dad[i][y];
    }
    return dad[0][x];
}

int query(int x, int y)
{
    int dif = lvl[x] - lvl[y], sol = INF;
    for(int i = 0; i < LMAX; i++)
        if(dif & (1 << i))
        {
            sol = min(sol, minim[i][x]);
            x = dad[i][x];
        }
    return sol;
}

void solve()
{
    ofstream out("atac.out");
    while(m--)
    {
        int lca = getLCA(X, Y), ans = min(query(X, lca), query(Y, lca));
        if(X == Y) ans = 0;
        if(m < p) out<<ans<<"\n";
        NX = (X * A + Y * B) % n + 1;
        NY = (Y * C + ans * D) % n + 1;
        X = NX; Y = NY;
    }
    out.close();
}

int main()
{
    citire();
    dfs(1, 0, 1, 0);
    buildAncestors();
    solve();
    return 0;
}