Cod sursa(job #203046)

Utilizator AndreyPAndrei Poenaru AndreyP Data 13 august 2008 10:52:28
Problema Atac Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.81 kb
#include<stdio.h>
#include<stdlib.h>
#define N 32010
#define M 96010
struct graf
{
	int nod,cost;
};
struct ajt
{
	int cine,cat;
};
graf *g[N];
int poz[N],n,m,p,X,Y,A,B,C,D,Z,cati[N],cate,euler[M],adancime[M],lg[M],a[20][M],nivel[M];
ajt strm[18][N];
inline int min1(int x,int y)
{
	if(adancime[x]<adancime[y])
		return x;
	return y;
}
inline int min(int x,int y)
{
	if(x<y)
		return x;
	return y;
}
void citire()
{
	int aux1,aux2;
	scanf("%d%d%d",&n,&m,&p);
	for(int i=2; i<=n; i++)
	{
		scanf("%d%d",&aux1,&aux2);
		strm[0][i].cat=aux2;
		strm[0][i].cine=aux1;
		cati[i]++;
		g[i]=(graf*)realloc(g[i],(cati[i]+2)*sizeof(graf));
		g[i][cati[i]].nod=aux1;
		g[i][cati[i]].cost=aux2;
		cati[aux1]++;
		g[aux1]=(graf*)realloc(g[aux1],(cati[aux1]+2)*sizeof(graf));
		g[aux1][cati[aux1]].nod=i;
		g[aux1][cati[aux1]].cost=aux2;
	}
	scanf("%d%d%d%d%d%d",&X,&Y,&A,&B,&C,&D);
}
void parcurg(int nod,int cost,int niv)
{
	++cate;
	euler[cate]=nod;
	adancime[cate]=cost;
	nivel[cate]=niv;
	poz[nod]=cate;
	for(int i=1; i<=cati[nod]; i++)
	{
		if(!poz[g[nod][i].nod])
		{
			parcurg(g[nod][i].nod,cost+g[nod][i].cost,niv+1);
			cate++;
			euler[cate]=nod;
			adancime[cate]=cost;
			nivel[cate]=niv;
		}
	}
}
void precalc()
{
	int i,j;
	for(i=1; i<=lg[n]; i++)
	{
		for(j=1; j<=n; j++)
		{
			if((strm[i-1][j].cine>1)&&(strm[i-1][j].cine))
			{
				strm[i][j].cat=min(strm[i-1][strm[i-1][j].cine].cat,strm[i-1][j].cat);
				strm[i][j].cine=strm[i-1][strm[i-1][j].cine].cine;
			}
		}
	}
	/*
	for(i=0; i<=lg[n]; i++)
	{
		for(j=1; j<=n; j++)
			printf("%d %d    ",strm[i][j].cine,strm[i][j].cat);
		printf("\n");
	}
	printf("\n");*/
}
void rmq()
{
	int i,j,aux,aux1;
	a[0][1]=1;
	for(i=2; i<=cate; i++)
	{
		lg[i]=lg[i>>1]+1;
		a[0][i]=i;
	}
	for(i=1; i<=lg[cate]; i++)
	{
		aux=cate-(1<<i)+1;
		aux1=1<<(i-1);
		for(j=1; j<=aux; j++)
			a[i][j]=min1(a[i-1][j],a[i-1][j+aux1]);
	}
	precalc();
}
int afla(int nod,int stram)
{
	int nnod=nivel[poz[nod]];
	int nstrm=nivel[poz[stram]];
	int care=nnod-nstrm;
	int nrez=nod,rez=200000;
	while((care)&&(nrez))
	{
		rez=min(rez,strm[lg[care]][nrez].cat);
		nrez=strm[lg[care]][nrez].cine;
		care-=(1<<lg[care]);
	}
	return rez;
}
void rezolva()
{
	int i,p1=m-p,dif,log,el1,el2,cmin,x,y;
	for(i=1; i<=m; i++)
	{
		if(poz[X]<poz[Y])
		{
			el1=X;
			el2=Y;
		}
		else
		{
			el1=Y;
			el2=X;
		}
		x=poz[el1]+1;
		y=poz[el2]-1;
		dif=y-x+1;
		log=lg[dif];
		cmin=min1(a[log][x],a[log][x+dif-(1<<log)]);
		Z=min(afla(X,euler[cmin]),afla(Y,euler[cmin]));
		if(X==Y)
			Z=0;
		X=(X*A+Y*B)%n+1;
		Y=(Y*C+Z*D)%n+1;
		if(p1<i)
			printf("%d\n",Z);
	}
}
int main()
{
	freopen("atac.in","r",stdin);
	freopen("atac.out","w",stdout);
	citire();
	parcurg(1,0,1);
	rmq();
	rezolva();
	return 0;
}