Cod sursa(job #1116529)

Utilizator SmarandaMaria Pandele Smaranda Data 22 februarie 2014 17:35:22
Problema Atac Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.56 kb
#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

const long N = 32001;
const long inf = (1ll << 31) - 1;

struct node {
	long x, cost;
};

long n, m, p, a [N], cost [N], dp [16][32001], dp2 [16][32001], t [N], nivel [N], p2 = 1, lim;
bool used [N];
vector <node> graph [N];

void read () {
	long i, g, h;
	node temp;
	scanf ("%ld%ld%ld", &n, &m, &p);
	for (i = 2; i <= n; i ++) {
		scanf ("%ld%ld", &g, &h);
		temp.x = g;
		temp.cost = h;
		graph [i].push_back (temp);
		temp.x = i;
		temp.cost = h;
		graph [g].push_back (temp);
	}
}

void dfs (long x)  {
	vector <node> :: iterator it;
	used [x] = 1;
	for (it = graph [x].begin (); it != graph [x].end (); ++ it)
		if (!used [(*it).x] ) {
			t [(*it).x] = x;
			cost [(*it).x] = (*it).cost;
			nivel [(*it).x] = nivel [x] + 1;
			dfs ((*it).x);
		}
}

long query (long x, long y) {
    long ans = inf, i;
    if (nivel [x] < nivel [y]) {
        for (i = lim; i >= 0; i --)
            if (nivel [dp [i][y]] >= nivel [x]) {
                ans = min (ans, dp2 [i][y]);
                y = dp [i][y];
            }
    }
    else
        if (nivel [x] > nivel [y]) {
            for (i = lim; i >= 0; i --)
                if (nivel [dp [i][x]] >= nivel [y]) {
                    x = dp [i][x];
                    ans = min (ans, dp2 [i][x]);
                }
            }
    if (x == y)
        return 0;

    for (i = lim; i >= 0; i --) { // cautare binara
        if (dp [i][x] != dp [i][y]) {
            ans = min (min (ans, dp2 [i][x]), dp2 [i][y]);
            x = dp [i][x];
            y = dp [i][y];
        }
    }
    ans = min (ans, dp2 [0][x]);
    ans = min (ans, dp2 [0][y]);
    return ans;
}

void solve () {
	long x, y, a, b, c, d, i, z, nx, ny, j;

	t [1] = 0;
	nivel [1] = 0;
	dfs (1);

	for (i = 1; i <= n; i ++) {
		dp [0][i] = t [i];
		dp2 [0][i] = cost [i];
	}

	for (i = 1; ; i ++) {
		p2 = p2 << 1;
		if (p2 > n)
			break;
        lim = i;
		for (j = 1; j <= n; j ++) {
			dp [i][j] = dp [i - 1][dp [i - 1][j]];
			dp2 [i][j] = min (dp2 [i - 1][j], dp2 [i - 1][dp [i - 1][j]]);
		}
	}

	scanf ("%ld%ld%ld%ld%ld%ld", &x, &y, &a, &b, &c, &d);
	for (i = 1; i <= m; i ++) {
        z = query (x, y);
	    nx =(x * a + y * b) % n + 1;
        ny =(y * c + z * d) % n + 1;
        x = nx;
        y = ny;
        if (i >= m - p + 1)
            printf ("%ld\n", z);
	}
}

int main () {

	freopen ("atac.in", "r", stdin);
	freopen ("atac.out", "w", stdout);

	read ();
	solve ();
	return 0;
}