Submission #957857

# Submission time Handle Problem Language Result Execution time Memory
957857 2024-04-04T12:22:19 Z Der_Vlapos Virus Experiment (JOI19_virus) C++17
0 / 100
9 ms 860 KB
// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #include <x86intrin.h>

#include <bits/stdc++.h>
#include <chrono>
#include <random>

// @author: Vlapos

namespace operators
{
	template <typename T1, typename T2>
	std::istream &operator>>(std::istream &in, std::pair<T1, T2> &x)
	{
		in >> x.first >> x.second;
		return in;
	}

	template <typename T1, typename T2>
	std::ostream &operator<<(std::ostream &out, std::pair<T1, T2> x)
	{
		out << x.first << " " << x.second;
		return out;
	}

	template <typename T1>
	std::istream &operator>>(std::istream &in, std::vector<T1> &x)
	{
		for (auto &i : x)
			in >> i;
		return in;
	}

	template <typename T1>
	std::ostream &operator<<(std::ostream &out, std::vector<T1> &x)
	{
		for (auto &i : x)
			out << i << " ";
		return out;
	}

	template <typename T1>
	std::ostream &operator<<(std::ostream &out, std::set<T1> &x)
	{
		for (auto &i : x)
			out << i << " ";
		return out;
	}
}

// name spaces
using namespace std;
using namespace operators;
// end of name spaces

// defines
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define pll pair<ll, ll>
#define f first
#define s second
#define uint unsigned int
#define all(vc) vc.begin(), vc.end()
// end of defines

// usefull stuff

void boost()
{
	ios_base ::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
}

inline int getbit(int &x, int &bt) { return (x >> bt) & 1; }

const int dx4[4] = {-1, 0, 0, 1};
const int dy4[4] = {0, -1, 1, 0};
const int dx8[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
const int dy8[8] = {-1, -0, 1, -1, 1, -1, 0, 1};

const ll INF = (1e18) + 500;
const int BIG = (1e9) * 2 + 100;
const int MAXN = (1e5) + 5;
const int MOD7 = (1e9) + 7;
const int MOD9 = (1e9) + 9;
const uint MODFFT = 998244353;

// #define int ll

const int maxN = 10;

vector<pair<vector<pii>, pii>> rules[maxN][maxN];

struct DSU
{
	map<pii, bool> is[maxN][maxN];
	pii pr[maxN][maxN];

	void init(int r, int c)
	{
		for (int i = 0; i < r; ++i)
			for (int j = 0; j < c; ++j)
			{
				pr[i][j] = {i, j};
				is[i][j][{i, j}];
			}
	}

	pii getRoot(pii c)
	{
		return pr[c.f][c.s] == c ? c : pr[c.f][c.s] = getRoot(pr[c.f][c.s]);
	}
};

struct test
{
	int m, r, c;

	bool good(int x, int y)
	{
		return x >= 0 and y >= 0 and x < r and y < c;
	}
	vector<vector<pii>> pr;
	vector<vector<int>> tin, fup;
	DSU dsu;

	int ans = BIG, cnt = 0;
	int timer = 0;

	void dfs(pii v)
	{
		tin[v.f][v.s] = fup[v.f][v.s] = ++timer;
		auto [x, y] = v;
		queue<pii> toV;
		for (auto &[nd, to] : rules[x][y])
			if (nd.size() == 1)
				toV.push(to);

		bool isGood = true;
		while (toV.size())
		{
			pii to = toV.front();
			to = dsu.getRoot(to);
			toV.pop();
			if (dsu.getRoot(to) == dsu.getRoot(v))
				continue;
			if (!tin[to.f][to.s])
			{
				dfs(to);
				fup[x][y] = min(fup[x][y], fup[to.f][to.s]);
				if (fup[to.f][to.s] <= tin[x][y])
				{
					to = dsu.getRoot(to);
					pii cur = v;
					assert(dsu.getRoot(v) == cur);
					// merge prev and cur
					if (dsu.is[cur.f][cur.s].size() > dsu.is[to.f][to.s].size())
						swap(dsu.is[cur.f][cur.s], dsu.is[to.f][to.s]);

					for (auto &[el, bf] : dsu.is[cur.f][cur.s])
						for (auto &[els, newTo] : rules[el.f][el.s])
						{
							int cnt1 = 0, cnt2 = 0;
							for (pii WTF : els)
								if (dsu.is[to.f][to.s].find(WTF) != dsu.is[to.f][to.s].end())
									cnt1++;
								else if (dsu.is[cur.f][cur.s].find(WTF) != dsu.is[cur.f][cur.s].end())
									cnt2++;
							if (cnt1 and cnt2 and cnt1 + cnt2 == els.size() and dsu.getRoot(newTo) != v)
								toV.push(newTo);
						}

					for (auto &[el, bf] : dsu.is[to.f][to.s])
						dsu.is[cur.f][cur.s][el];
					dsu.pr[to.f][to.s] = cur;
					dsu.is[to.f][to.s].clear();
				}
				else
					isGood = false;
			}
			else if (tin[v.f][v.s] > tin[to.f][to.s])
			{
				fup[x][y] = min(tin[to.f][to.s], fup[x][y]);
				isGood = false;
			}
		}

		if (tin[x][y] == fup[x][y] and isGood)
		{
			pii cur = dsu.getRoot(v);
			int VAL = (int)dsu.is[cur.f][cur.s].size();
			if (ans > VAL)
			{
				ans = VAL;
				cnt = VAL;
			}
			else if (ans == VAL)
			{
				cnt += VAL;
			}
		}
	}

	void solve(int testcase)
	{
		boost();

		cin >> m >> r >> c;

		dsu.init(r, c);
		pr.resize(r, vector<pii>(c));
		tin.resize(r, vector<int>(c));
		fup.resize(r, vector<int>(c));
		string s;
		cin >> s;
		s = s + s;
		m *= 2;

		// const int dx4[4] = {-1, 0, 0, 1};
		// const int dy4[4] = {0, -1, 1, 0};
		map<char, int> dist;
		dist['N'] = 0;
		dist['W'] = 1;
		dist['E'] = 2;
		dist['S'] = 3;

		vector<int> longest(1 << 4);
		for (int i = 1; i < (1 << 4); ++i)
		{
			int cnt = 0, cur = 0;
			for (int j = 0; j < m; ++j)
			{
				if ((i >> (dist[s[j]])) & 1)
					cur++;
				else
					cur = 0;
				cnt = max(cnt, cur);
			}
			if (cnt == 2 * m)
				longest[i] = BIG;
			else
				longest[i] = cnt;
		}

		vector<vector<int>> u(r, vector<int>(c));
		cin >> u;
		for (int i = 0; i < r; ++i)
			for (int j = 0; j < c; ++j)
				if (!u[i][j])
					u[i][j] = BIG + 10;

		for (int i = 0; i < r; ++i)
			for (int j = 0; j < c; ++j)
				for (int mask = 0; mask < (1 << 4); ++mask)
				{
					bool cur = true;
					for (int val = 0; val < 4; ++val)
					{
						int tox = i + dx4[val];
						int toy = j + dy4[val];
						cur &= (good(tox, toy) or !((mask >> val) & 1));
					}
					if (cur and u[i][j] <= longest[mask])
					{
						vector<pii> els;
						for (int val = 0; val < 4; ++val)
							if ((mask >> val) & 1)
							{
								int tox = i + dx4[val];
								int toy = j + dy4[val];
								els.pb({tox, toy});
							}
						// cerr << mask << " " << longest[mask] << " | " << els << " -> " << mp(i, j) << "\n";
						for (int val = 0; val < 4; ++val)
							if ((mask >> val) & 1)
							{
								int tox = i + dx4[val];
								int toy = j + dy4[val];
								rules[tox][toy].pb({els, {i, j}});
							}
					}
				}

		for (int i = 0; i < r; ++i)
			for (int j = 0; j < c; ++j)
				if (!tin[i][j] and u[i][j] != BIG + 10)
					dfs({i, j});
		if (ans == BIG)
			ans = 0, cnt = 0;

		cout << ans << '\n'
			 << cnt << '\n';
	}
};

main()
{
	boost();
	int q = 1;
	// cin >> q;
	for (int i = 0; i < q; i++)
	{
		test t;
		t.solve(i);
	}
	return 0;
}
//[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]//
//                                                                                    //
//                               Coded by Der_Vlἀpos                                  //
//                                                                                    //
//[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]//

Compilation message

virus.cpp: In member function 'void test::dfs(std::pair<int, int>)':
virus.cpp:174:42: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  174 |        if (cnt1 and cnt2 and cnt1 + cnt2 == els.size() and dsu.getRoot(newTo) != v)
      |                              ~~~~~~~~~~~~^~~~~~~~~~~~~
virus.cpp: At global scope:
virus.cpp:301:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
  301 | main()
      | ^~~~
# Verdict Execution time Memory Grader output
1 Runtime error 1 ms 604 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 0 ms 348 KB Output is correct
2 Correct 9 ms 860 KB Output is correct
3 Runtime error 1 ms 604 KB Execution killed with signal 11
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Runtime error 1 ms 604 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -