85 pts 球条
查看原帖
85 pts 球条
642144
This_Rrhar楼主2023/11/20 20:32

WA ON #6,#9,#10。

#include <bits/stdc++.h>
using namespace std;
#define _r return*this
#define _o &operator
namespace IO
{
	const int _S = 1 << 21;
	char b[_S], *p1 = b, *p2 = b, pb[_S], *pp = pb;
	void fl()
	{
		fwrite(pb, 1, pp - pb, stdout), pp = pb;
	}
	struct input
	{
		char gc()
		{
			if (p1 == p2)p2 = (p1 = b) + fread(b, 1, _S, stdin);
			return p1 == p2 ? ' ' : *p1++;
		}
		input _o >> (char&c)
		{
			do c = gc();
			while (c == ' ' || c == '\n' || c == '\r' || c == '\t');
			_r;
		}
		template<class T>input _o >> (T&x)
		{
			char c = gc();
			T f = 1;
			for (x = 0; !isdigit(c);)(c == '-' ? f = -1 : 1), c = gc();
			while (isdigit(c))x = (x * 10) + (c ^ 48), c = gc();
			x *= f;
			_r;
		}
		input() {}
	} in;
	struct output
	{
		void pt(char c)
		{
			*pp++ = c;
			if (pp - pb == _S)fl();
		}
		output _o << (char c)
		{
			pt(c);
			_r;
		}
		template<class T>output _o << (T x)
		{
			if (!x)
			{
				pt(48);
				_r;
			}
			if (x < 0)pt('-'), x = -x;
			int s[64], t = 0;
			while (x)s[++t] = x % 10, x /= 10;
			while (t)pt(s[t--] + 48);
			_r;
		}
		output _o << (const char*s)
		{
			int c = 0;
			while (s[c])pt(s[c++]);
			_r;
		}
		output() {}
	} out;
	struct fe
	{
		~fe()
		{
			fl();
		}
	} fls;
}
using IO::in;
using IO::out;
using ll = long long;

#define MOD 590027
#define N 600000

ll n, m;
ll x, y;
bool mp[20][20];

struct answer
{
	ll mn, mx;
	void update(answer B)
	{
		mn = min(mn, B.mn), mx = max(mx, B.mx);
	}
};

ll dp[2][N];
ll total;

ll bit[30];
void init()
{
	for (int i = 1; i <= 25; i++)bit[i] = i << 1;
}

ll sta[2][N], tot[2];
ll pre = 1, cnt;

struct hash_node
{
	ll v, nxt;
} e[N];
ll p[N], pos;
void ins(ll st, ll v)
{
	ll dis = st % MOD;
	for (int i = p[dis]; i; i = e[i].nxt)
		if (sta[cnt][e[i].v] == st)
		{
			dp[cnt][e[i].v] = max(dp[cnt][e[i].v], v);
			return;
		}
	sta[cnt][++tot[cnt]] = st, dp[cnt][tot[cnt]] = v;
	e[++pos] = {tot[cnt], p[dis]}, p[dis] = pos;
}

void PlugDP()
{
	tot[cnt] = 1;
	for (int i = n + 2; i >= 1; i--)
	{
		for (int j = 1; j <= tot[cnt]; j++)sta[cnt][j] <<= 2;
		for (int j = 1; j <= n + 2; j++)
		{
			pos = 0, memset(p, 0, sizeof(p)), swap(pre, cnt), tot[cnt] = 0;
			for (int k = 1; k <= tot[pre]; k++)
			{
				ll st = sta[pre][k], ans = dp[pre][k], d = (st >> bit[j]) & 3, r = (st >> bit[j - 1]) & 3;
				if (!mp[i][j])
				{
					if (!d && !r)ins(st, ans);
				}
				else if (!d && !r)
				{
					if (mp[i - 1][j] && mp[i][j + 1])ins(st + (1 << bit[j - 1]) + (1 << (bit[j] + 1)), ans + 1);
					if (i ^ (n + 2) || j ^ 1)ins(st, ans);
				}
				else if (!d && r)
				{
					if (mp[i - 1][j])ins(st, ans + 1);
					if (mp[i][j + 1])ins(st + r * ((1 << bit[j]) - (1 << bit[j - 1])), ans + 1);
				}
				else if (d && !r)
				{
					if (mp[i][j + 1])ins(st, ans + 1);
					if (mp[i - 1][j])ins(st + d * ((1 << bit[j - 1]) - (1 << bit[j])), ans + 1);
				}
				else if (d == 1 && r == 1)
				{
					ll t = 1;
					for (int l = j + 1; l <= n; l++)
					{
						if (((st >> bit[l]) & 3) == 1)t++;
						else if (((st >> bit[l]) & 3) == 2)t--;
						if (!t)
						{
							ins(st - (1 << bit[j - 1]) - (1 << bit[j]) - (1 << bit[l]), ans + 1);
							break;
						}
					}
				}
				else if (d == 2 && r == 2)
				{
					ll t = 1;
					for (int l = j - 2; l >= 0; l--)
					{
						if (((st >> bit[l]) & 3) == 1)t--;
						else if (((st >> bit[l]) & 3) == 2)t++;
						if (!t)
						{
							ins(st - (1 << (bit[j - 1] + 1)) - (1 << (bit[j] + 1)) + (1 << bit[l]), ans + 1);
							break;
						}
					}
				}
				else if (d == 1 && r == 2)ins(st - (1 << (bit[j - 1] + 1)) - (1 << bit[j]), ans + 1);
				else if (d == 2 && r == 1)
				{
					if (i == 1 && j == n + 2)total = max(total, ans);
				}
			}
		}
	}
}

const pair<ll, ll>d[] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
bool mq[20][20], vis[20][20];
queue<pair<ll, ll>>q;
ll dis[20][20];
void SPFA()
{
	memset(dis, 0x3f, sizeof(dis));
	dis[n][1] = 0, q.push({n, 1}), vis[n][1] = true;
	while (!q.empty())
	{
		x = q.front().first, y = q.front().second, q.pop();
		for (pair<ll, ll>i : d)
		{
			ll nx = x + i.first, ny = y + i.second;
			if (1 <= nx && nx <= n && 1 <= ny && ny <= n && !vis[nx][ny])
				vis[nx][ny] = true, dis[nx][ny] = dis[x][y] + 1, q.push({nx, ny});
		}
	}
}

int main()
{
	in >> n >> m;
	for (int i = 1; i <= n + 2; i++)for (int j = 1; j <= n + 2; j++)mp[i][j] = true;
	for (int i = 2; i <= n + 1; i++)mp[i][2] = mp[2][i] = false;
	while (m--)in >> x >> y, mp[x + 2][y + 2] = false;
	init(), PlugDP(), SPFA(), out << total - dis[1][n] - n * 2 - 5;
}
2023/11/20 20:32
加载中...