Cod sursa(job #86075)

Utilizator sima_cotizoSima Cotizo sima_cotizo Data 23 septembrie 2007 14:39:25
Problema Curcubeu Scor 20
Compilator cpp Status done
Runda Autumn Warmup 2007, Runda 2 Marime 2.5 kb
#include <cstdio>
// #include <cstring>

#define FIN "curcubeu.in"
#define FOUT "curcubeu.out"
#define MAX 1000100
#define actual(X) X[i]=(X[i-1]*i)%N
#define __debug__ 0

inline long max(long a, long b) {
	return a>b ? a : b;
}
inline long min(long a, long b) {
	return a<b ? a : b;
}

const char newline[] = "------------------------------------\n";

long A[MAX], B[MAX], C[MAX];
long R[MAX];
long N;

void fill(long x, long y, long z) {
	long i;
    if ( x>y ) {
    	long t = x; x = y; y = t;
    }
	for (i=x; i<=y; ++i)
		R[i] = z;
}

void brut() {
	long i;
	fill(A[1],B[1],C[1]);
	for (i=2; i<=N-1; ++i) {
		actual(A);
		actual(B);
		actual(C);
		fill(A[i],B[i],C[i]);
	}
}

class arbint {
	private:
		long *A, *dest;
		long fst,fdr,cul;
		long nr;
		void rec_fill(long root, long st, long dr) {
			if ( __debug__ ) {
				fprintf(stderr, "Procesam nodul %ld, capete(%ld %ld)\n", root, st,dr);
			}
			if (fst<=st && dr<=fdr) {
				A[root] = cul;
				return;
			}
			if ( A[root] ) A[2*root+1] = A[2*root+2] = A[root];
			A[root] = 0;
			long m = (st+dr)/2;
			if ( fst<=m ) rec_fill(2*root+1,st,m);
			if ( m<fdr ) rec_fill(2*root+2,m+1,dr);
		}
		void rec_get(long root, long st, long dr) {
			if ( __debug__ && A[root && A[root]] )
				fprintf(stderr, "Nodul %ld acopera (%ld %ld) si are %ld\n", root, st,dr,A[root]);
			if ( st==dr ) {
				R[st] = A[root];
				return;
			}
			if ( A[root] ) {
				long i;
				for (i=st; i<=dr; ++i)
					R[i] = A[root];
			} else {
				long m=(st+dr)/2;
				rec_get(2*root+1,st,m);
				rec_get(2*root+2,m+1,dr);
			}
		}
	public:
		arbint(long x) {
			nr = x;
			A = new long[4*x];
			if ( __debug__ )
				fprintf(stderr, "Arbint, alocat pentru nr=%ld, pointer : %p\n%s",nr, A, newline);
		}
		void fill(long x,long y,long z) {
			fst = x; fdr = y; cul = z;
			rec_fill(0,1,nr);
			if ( __debug__ )
				fprintf(stderr, "Umplut zona (%ld %ld) cu %ld\n%s",x,y,z,newline);
		}
		void scoate(long *R) {
			dest = R;
			rec_get(0,1,nr);
			if ( __debug__ )
				fprintf(stderr,"Scos continutul in %p\n%s", R,newline);
		}
} *arb;

void arbori() {
	arb = new arbint(N-1);
	arb -> fill(min(A[1], B[1]), max(A[1], B[1]), C[1]);
	long i;
	for (i=2; i<=N-1; ++i) {
		actual(A);
		actual(B);
		actual(C);
		arb -> fill(min(A[i], B[i]), max(A[i], B[i]), C[i]);
	}
	arb -> scoate(R);
}


int main() {
	freopen(FIN, "r", stdin);
	scanf("%ld %ld %ld %ld", &N, A+1, B+1, C+1);
	fclose(stdin);
	
//	brut();
	arbori();

	freopen(FOUT, "w", stdout);
	long i;
	for (i=1; i<N; ++i)
		printf("%ld\n", R[i]);
	fclose(stdout);
	return 0;
}