Cod sursa(job #17791)

Utilizator wefgefAndrei Grigorean wefgef Data 16 februarie 2007 21:21:28
Problema Pedefe Scor 65
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.38 kb
#include <cstdio>
#include <string.h>

#define mod 666013

#define Nmax 512
#define Pmax 128
#define Rmax 512

int n, m, p;
int s1[Nmax], s2[Nmax], s3[Pmax];
int S1[Nmax], S2[Nmax];
int aib1[Rmax], aib2[Rmax];
int A[Nmax][Nmax], B[Nmax][Nmax];

void readdata()
{
	freopen("pedefe.in", "r", stdin);
	freopen("pedefe.out", "w", stdout);
	
	int i;
	scanf("%d %d %d", &n, &m, &p);
	for (i = 1; i <= n; ++i) scanf("%d", &s1[i]);
	for (i = 1; i <= m; ++i) scanf("%d", &s2[i]);
	for (i = 1; i <= p; ++i) scanf("%d", &s3[i]);
}

void inline update1(int k, int val)
{
	while (k < Rmax)
	{
		aib1[k] += val;
		if (aib1[k] > mod) aib1[k] %= mod;
		k += k & (k ^ (k-1));
	}
}

void inline update2(int k, int val)
{
	while (k < Rmax)
	{
		aib2[k] += val;
		if (aib2[k] > val) aib2[k] %= mod;
		k += k & (k ^ (k-1));
	}
}

int inline interog1(int k)
{
	int rez = 0;
	while (k)
	{
		rez += aib1[k];
		if (rez > mod) rez %= mod;
		k -= k & (k ^ (k-1));
	}
	return rez;
}

int inline interog2(int k)
{
	int rez = 0;
	while (k)
	{
		rez += aib2[k];
		if (rez > mod) rez %= mod;
		k -= k & (k ^ (k-1));
	}
	return rez;
}

void solve()
{
	int i, j, k, rez = 0;	
	
	S1[0] = 1;
	A[0][0] = 1;
	for (i = 1; i <= n; ++i)
	{
		for (j = 1; j <= m; ++j)
		{
			if (s1[i] == s2[j])
				for (k = j-1; k >= 0; --k)
				{
					if (s2[k] < s2[j]) A[i][j] += S1[k];
					if (A[i][j] > mod) A[i][j] %= mod;
				}
		}
		for (j = 1; j <= m; ++j)
		{
			S1[j] += A[i][j];
			if (S1[j] > mod) S1[j] %= mod;
		}
	}

	for (k = 1; k <= p; ++k)
	{
		memset(B, 0, sizeof(B));
		memset(S1, 0, sizeof(S1));
		memset(S2, 0, sizeof(S2));	

		for (i = 1; i <= n; ++i)
		{
			memset(aib1, 0, sizeof(aib1));
			memset(aib2, 0, sizeof(aib2));				
			for (j = 0; j <= m; ++j)
			{
				S1[j] += A[i-1][j];
				if (S1[j] > mod) S1[j] %= mod;
				S2[j] += B[i-1][j];
				if (S2[j] > mod) S2[j] %= mod;
			}			
			for (j = 1; j <= m; ++j)
			{
				update1(s2[j-1]+1, S1[j-1]);
				update2(s2[j-1]+1, S2[j-1]);				
				if (s1[i] == s2[j])
					if (s1[i] == s3[k]) B[i][j] = interog1(s1[i]+1);
					else B[i][j] = interog2(s1[i]+1);
			}
		}
		memcpy(A, B, sizeof(A));
	}
	
	for (i = 1; i <= n; ++i)
	for (j = 1; j <= m; ++j)
	{
		rez += A[i][j];
		if (rez > mod) rez %= mod;
	}
	printf("%d\n", rez);
}

int main()
{
	readdata();
	solve();
	return 0;
}