Cod sursa(job #1581636)

Utilizator iordache.bogdanIordache Ioan-Bogdan iordache.bogdan Data 26 ianuarie 2016 23:07:22
Problema Pedefe Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.06 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

ifstream fin("pedefe.in");
ofstream fout("pedefe.out");

const int mod = 666013;

struct Aib {

private:

	int dim;
	vector<int> aib;

	inline int lsb(int x) {

		return (x & (-x));

	}

public:

	Aib(int dim) {

		this->dim = dim;
		aib.resize(dim + 5);

	}

	void update(int pos, int val) {

		for (int i = pos; i <= dim; i += lsb(i))
			aib[i] = (aib[i] + val >= mod ? aib[i] + val - mod : aib[i] + val);

	}

	int query(int pos) {

		int ans = 0;
		for (int i = pos; i; i -= lsb(i))
			ans = (ans + aib[i] >= mod ? ans + aib[i] - mod : ans + aib[i]);

		return ans;

	}

} *aib;

int s1[520], s2[520], s3[520], cnt[520];

int dp[2][520][520];

int main() {

	int n, m, p;
	fin >> n >> m >> p;

	for (int i = 1; i <= n; ++i)
		fin >> s1[i];
	for (int i = 1; i <= m; ++i)
		fin >> s2[i];
	for (int i = 1; i <= p; ++i)
		fin >> s3[i];

	int OLD = 0, NEW = 1;
	dp[0][0][0] = 1;
	for (int k = 0; k <= p; ++k) {

		memset(cnt, 0, sizeof cnt);

		for (int i = 1; i <= n; ++i) {

			aib = new Aib(500);

			for (int j = 1; j <= m; ++j) {

				dp[NEW][i][j] = 0;

				if (s1[i] == s2[j]) {

					int add = aib->query(s1[i]);

					if (k == 0)
						add = (add + 1 == mod ? 0 : add + 1);

					if (k < p && s1[i] == s3[k + 1])
						dp[NEW][i][j] = (dp[NEW][i][j] + add >= mod ? dp[NEW][i][j] + add - mod : dp[NEW][i][j] + add);
					else
						dp[OLD][i][j] = (dp[OLD][i][j] + add >= mod ? dp[OLD][i][j] + add - mod : dp[OLD][i][j] + add);

				}
				else
					dp[OLD][i][j] = 0;

				aib->update(s2[j], cnt[j]);
				cnt[j] = (cnt[j] + dp[OLD][i][j] >= mod ? cnt[j] + dp[OLD][i][j] - mod : cnt[j] + dp[OLD][i][j]);

			}

			delete aib;

		}

		swap(OLD, NEW);

	}

	int ans = 0;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= m; ++j)
			ans = (ans + dp[NEW][i][j] >= mod ? ans + dp[NEW][i][j] - mod : ans + dp[NEW][i][j]);

	fout << ans << '\n';

	return 0;

}

//Trust me, I'm the Doctor!