Cod sursa(job #80768)

Utilizator peanutzAndrei Homorodean peanutz Data 29 august 2007 21:05:20
Problema Atac Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.73 kb
#include <stdio.h>
#include <vector>

using namespace std;

#define NMAX 32090
#define EULERMAX NMAX*2
#define INFI 0x3f3f3f3f

vector<int> list[NMAX];
int n, m, p;
int x, y, a, b, c, d;
int adancime[EULERMAX], euler[EULERMAX];
int h = 1;
int poz[NMAX];
int s[40][NMAX], minim[40][NMAX];
int itree[EULERMAX*3];

#define pb push_back
#define sz size()
//#define MIN(a, b) ((a) < (b)) ? (a) : (b)

inline int MIN(int a, int b)
{
 return (a < b) ? a : b;
}

void read()
{
	int i, x, y, c;
	scanf("%d%d%d", &n, &m, &p);
	for(i = 2; i <= n; ++i)
	{
		scanf("%d%d", &y, &c);
		
		x = i;
		if(x > y)
		{
			int aux = x;
			x = y;
			y = aux;
		}
		
		list[x].pb(y);

		s[0][y] = x;
		minim[0][y] = c;
	}
	//scanf("%d %d %d %d %d %d", &x, &y, &a, &b, &c, &d);
    //printf("%d %d\n", x, y);
}

void pre()
{
	int i = 1, j, p = 1, x, y;

	while(p <= n)
	{
		for(j = 1; j <= n; ++j)
			minim[i][j] = MIN(minim[i-1][j], minim[i-1][ s[i-1][j] ]), s[i][j] = s[i-1][ s[i-1][j] ];
	 	++i, p <<= 1;
	}
}

void df(int x)
{
    int y;
	vector<int> :: iterator it, fin = list[x].end();

	for(it = list[x].begin(); it != fin; ++it)
	{
		poz[*it] = h;
		adancime[h] = 1+adancime[ poz[x] ];
		euler[h++] = *it;

		df(*it);

		adancime[h] = adancime[ poz[x] ];
		euler[h++] = x;
	}
}

#define mij(i, j) ((i)+(j)) >> 1
#define left(i) ((i)<<1)
#define right(i) ((i)<<1)+1
//#define min(a, b) (a < b) ? a : b
inline int MAX(int a, int b) { return (a > b) ? a : b; }

void update(int r, int st, int dr, int x, int y)
{
	if(adancime[ itree[r] ] > adancime[x])
		itree[r] = x;

	if(st == dr)
		return;

	int m = mij(st, dr);

	if(y <= m)
		update(left(r), st, m, x, y);
	else
		update(right(r), m+1, dr, x, y);
}

int querylca(int r, int st, int dr, int x, int y)
{
	if(x <= st  &&  y >= dr)
		return 	itree[r];
	int t = 0, m = mij(st, dr);

	if(x <= m)
		t = querylca(left(r), st, m, x, y);
	if(y > m)
		if(adancime[t] > adancime[ querylca(right(r), m+1, dr, x, y) ])
			t = querylca(right(r), m+1, dr, x, y);

	return t;
}

int querymin(int x, int y)
{
	int i, p, qmin = INFI;

    //printf("min %d %d = ", x, y);
	while(y && x != 0)
	{
		i = -1, p = 1;
		while(p <= y)
			p <<= 1, ++i;
		
		qmin = MIN(qmin, minim[i][x]);
		y -= (p >> 1);
		x = s[i][x];
	}
    //printf("%d\n", qmin);
	return qmin;
}

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

	read();
	pre();

	poz[1] = 1;
	euler[1] = 1;
	adancime[1] = 1;
	h = 2;
	df(1);
	--h;

	adancime[0] = INFI;
    int i;
    for(i = 1; i <= h; ++i)
          update(1, 1, h, i, i);

	int z, ancestor;
     /*
     for(i = 1; i <= h; ++i)
     printf("%d ", euler[i]);
     printf("\n");
     for(i = 1; i <= h; ++i)
     printf("%d ", adancime[i]);
     printf("\n");
     for(i = 1; i <= n; ++i)
     printf("%d ", poz[i]);
     printf("\n");
     */

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

    //printf("%d %d %d\n", minim[1][4], minim[0][2], minim[0][5]);
    //printf("%d\n", adancime[poz[5]], poz[5]);
	for(i = 1; i <= m; ++i)
	{
        //printf("%d %d %d %d %d\n", x, y, querylca(1, 1, h, poz[x], poz[y]), poz[x], poz[y]);
		ancestor = euler[ querylca(1, 1, h, MIN(poz[x], poz[y]), MAX(poz[x], poz[y])) ];
        //printf("%d %d %d\n", x, y, ancestor);//, querylca(1, 1, h, poz[x], poz[y]));

        //return 0;

		z = MIN(querymin(x, adancime[poz[x]]-adancime[poz[ancestor]]), querymin(y, adancime[poz[y]]-adancime[poz[ancestor]]));

		if(i > m-p)
			printf("%d\n", z);

		x = ((x*a + y*b) % n) + 1;
		y = ((y*c + z*d) % n) + 1;
        //return 0;
	}

	return 0;
}