답안 #958174

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
958174 2024-04-05T05:23:10 Z Der_Vlapos 바이러스 (JOI19_virus) C++17
14 / 100
437 ms 85704 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 = 810 * 810;
// const int maxN = 810 * 810;

bool rules[maxN][16];

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

	void init(int n)
	{
		for (int i = 0; i < n; ++i)
		{
			pr[i] = i;
			is[i][i];
		}
	}

	int getRoot(int c)
	{
		return pr[c] == c ? c : pr[c] = getRoot(pr[c]);
	}
};

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<int> tin, fup;
	DSU dsu;

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

	bool dfs(int v)
	{
		tin[v] = fup[v] = ++timer;
		queue<int> toV;
		for (int d = 0; d < 4; ++d)
		{
			int tox = (v / c) + dx4[d];
			int toy = (v % c) + dy4[d];
			if (good(tox, toy) and rules[tox * c + toy][1 << (3 - d)])
				toV.push(tox * c + toy);
		}

		bool isGood = true;
		while (toV.size())
		{
			int to = toV.front();
			to = dsu.getRoot(to);
			toV.pop();
			if (dsu.getRoot(to) == dsu.getRoot(v))
				continue;
			// cout << v << " -> " << to << '\n';
			if (!tin[to])
			{
				isGood &= dfs(to);
				fup[v] = min(fup[v], fup[to]);
				if (fup[to] <= tin[v])
				{
					assert(dsu.getRoot(to) == to);
					assert(dsu.getRoot(v) == v);
					// merge prev and cur
					// cout << "merging" << v << " " << to << '\n';
					if (dsu.is[v].size() < dsu.is[to].size())
						swap(dsu.is[v], dsu.is[to]);

					for (auto &[el, bf] : dsu.is[to])
						for (int d = 0; d < 4; ++d)
						{
							int tox = (el / c) + dx4[d];
							int toy = (el % c) + dy4[d];
							if (good(tox, toy))
							{
								int cnt1 = 0, cnt2 = 0;
								int mask = 0;
								for (int d = 0; d < 4; ++d)
								{
									int totox = (v / c) + dx4[d];
									int totoy = (v % c) + dy4[d];
									if (dsu.is[v].find(totox * c + totoy) != dsu.is[v].end())
									{
										cnt1++;
										mask |= (1 << d);
									}
									else if (dsu.is[to].find(totox * c + totoy) != dsu.is[to].end())
									{
										cnt2++;
										mask |= (1 << d);
									}
								}
								if (rules[tox * c + toy][mask] and cnt1 and cnt2)
									toV.push(tox * c + toy);
							}
						}

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

		if (tin[v] == fup[v] and isGood)
		{
			assert(dsu.getRoot(v) == v);
			int VAL = (int)dsu.is[v].size();
			if (ans > VAL)
			{
				ans = VAL;
				cnt = VAL;
			}
			else if (ans == VAL)
			{
				cnt += VAL;
			}
		}
		tin[v] = BIG;
		return isGood;
	}

	void solve(int testcase)
	{
		boost();

		cin >> m >> r >> c;

		dsu.init(r * c);
		tin.resize(r * c);
		fup.resize(r * 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 == 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])
					{
						rules[i * c + j][mask] = 1;
					}
				}

		for (int i = 0; i < r; ++i)
			for (int j = 0; j < c; ++j)
				if (!tin[i * c + j] and u[i][j] != BIG + 10)
					dfs(i * c + 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:307:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
  307 | main()
      | ^~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 28 ms 33880 KB Output is correct
2 Correct 220 ms 82776 KB Output is correct
3 Correct 240 ms 85704 KB Output is correct
4 Correct 208 ms 82780 KB Output is correct
5 Correct 206 ms 85076 KB Output is correct
6 Correct 21 ms 33880 KB Output is correct
7 Correct 437 ms 84004 KB Output is correct
8 Correct 117 ms 54264 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 21 ms 33624 KB Output is correct
2 Correct 31 ms 34136 KB Output is correct
3 Incorrect 58 ms 34140 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 28 ms 33880 KB Output is correct
2 Correct 220 ms 82776 KB Output is correct
3 Correct 240 ms 85704 KB Output is correct
4 Correct 208 ms 82780 KB Output is correct
5 Correct 206 ms 85076 KB Output is correct
6 Correct 21 ms 33880 KB Output is correct
7 Correct 437 ms 84004 KB Output is correct
8 Correct 117 ms 54264 KB Output is correct
9 Correct 21 ms 33624 KB Output is correct
10 Correct 31 ms 34136 KB Output is correct
11 Incorrect 58 ms 34140 KB Output isn't correct
12 Halted 0 ms 0 KB -