QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#67459#2576. 麻将alpha1022100 ✓114ms10308kbC++144.0kb2022-12-10 16:10:042022-12-10 16:10:05

Judging History

This is the latest submission verdict.

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-12-10 16:10:05]
  • Judged
  • Verdict: 100
  • Time: 114ms
  • Memory: 10308kb
  • [2022-12-10 16:10:04]
  • Submitted

answer

#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
const int N = 100;
const int M = 2092;
const int mod = 998244353;
inline int fpow(int a,int b)
{
	int ret = 1;
	for(;b;b >>= 1)
		(b & 1) && (ret = (long long)ret * a % mod),a = (long long)a * a % mod;
	return ret;
}
int n,a[N + 5];
struct Matrix
{
	int a[3][3];
	inline int *operator[](const int &x)
	{
		return a[x];
	}
	inline const int *operator[](const int &x) const
	{
		return a[x];
	}
	inline Matrix()
	{
		for(register int i = 0;i < 3;++i)
			for(register int j = 0;j < 3;++j)
				a[i][j] = -1;
	}
	inline bool operator<(const Matrix &o) const
	{
		for(register int i = 0;i < 3;++i)
			for(register int j = 0;j < 3;++j)
				if(a[i][j] ^ o[i][j])
					return a[i][j] < o[i][j];
		return 0;
	}
	inline bool operator!=(const Matrix &o) const
	{
		for(register int i = 0;i < 3;++i)
			for(register int j = 0;j < 3;++j)
				if(a[i][j] ^ o[i][j])
					return 1;
		return 0;
	}
	inline void trans(Matrix &o,int x) const
	{
		for(register int i = 0;i < 3;++i)
			for(register int j = 0;j < 3;++j)
				if(~a[i][j])
					for(register int k = 0;k < 3 && i + j + k <= x;++k)
						o[j][k] = max(o[j][k],a[i][j] + i + (x - i - j - k) / 3),
						o[j][k] = min(o[j][k],4);
	}
	inline bool hou() const
	{
		for(register int i = 0;i < 3;++i)
			for(register int j = 0;j < 3;++j)
				if(a[i][j] == 4)
					return 1;
		return 0;
	}
};
struct node
{
	Matrix jantou[2];
	int toitsu;
	inline bool operator<(const node &o) const
	{
		if(toitsu ^ o.toitsu)
			return toitsu < o.toitsu;
		if(jantou[0] != o.jantou[0])
			return jantou[0] < o.jantou[0];
		if(jantou[1] != o.jantou[1])
			return jantou[1] < o.jantou[1];
		return 0;
	}
	inline void clear()
	{
		jantou[0] = jantou[1] = Matrix(),toitsu = 0;
	}
	inline void begin()
	{
		clear(),jantou[0][0][0] = 0;
	}
	inline void end()
	{
		clear(),toitsu = -1;
	}
	inline node()
	{
		clear();
	}
	inline node(int op)
	{
		op ? end() : begin();
	}
	inline bool hou() const
	{
		if(toitsu >= 7)
			return 1;
		if(jantou[1].hou())
			return 1;
		return 0;
	}
	inline node operator+(int x) const
	{
		if(toitsu == -1)
			return *this;
		node ret;
		x >= 2 && (jantou[0].trans(ret.jantou[1],x - 2),1);
		jantou[0].trans(ret.jantou[0],x);
		jantou[1].trans(ret.jantou[1],x);
		ret.toitsu = toitsu + (x >= 2);
		ret.hou() && (ret.end(),1);
		return ret;
	}
} q[M + 5];
int head,tail;
int tot,e[M + 5][5],ed;
map<node,int> id;
inline void bfs()
{
	id[q[++tail] = node(0)] = ++tot;
	for(register node p,dir;head < tail;)
	{
		p = q[++head];
		int x = id[p];
		for(register int i = 0;i <= 4;++i)
		{
			dir = p + i;
			if(id.count(dir))
				e[x][i] = id[dir];
			else
				e[x][i] = id[dir] = ++tot,q[++tail] = dir;
		}
	}
	ed = id[node(1)];
}
int fac[(N << 2) + 5],ifac[(N << 2) + 5];
int f[2][(N << 2) + 5][M + 5],ans;
int main()
{
	bfs();
	scanf("%d",&n),fac[0] = 1;
	for(register int i = 1;i <= (n << 2);++i)
		fac[i] = (long long)fac[i - 1] * i % mod;
	ifac[n << 2] = fpow(fac[n << 2],mod - 2);
	for(register int i = n << 2;i;--i)
		ifac[i - 1] = (long long)ifac[i] * i % mod;
	int x;
	for(register int i = 1;i <= 13;++i)
		scanf("%d%*d",&x),++a[x];
	f[0][0][id[node(0)]] = 1;
	for(register int i = 1;i <= n;++i)
	{
		memset(f[i & 1],0,sizeof f[i & 1]);
		for(register int j = 0;j <= (n << 2) - 13;++j)
			for(register int k = 1;k <= tot;++k)
				if(f[(i & 1) ^ 1][j][k])
					for(register int l = 0;l <= 4 - a[i] && i + l <= (n << 2) - 13;++l)
						f[i & 1][j + l][e[k][a[i] + l]] = (f[i & 1][j + l][e[k][a[i] + l]] + (long long)f[(i & 1) ^ 1][j][k] * fac[4 - a[i]] % mod * ifac[l] % mod * ifac[4 - a[i] - l] % mod) % mod;
	}
	for(register int i = 1;i <= (n << 2) - 13;++i)
		for(register int j = 1;j <= tot;++j)
			(j ^ ed) && (ans = (ans + (long long)f[n & 1][i][j] * fac[i] % mod * fac[(n << 2) - 13 - i] % mod) % mod);
	ans = ((long long)ans * ifac[(n << 2) - 13] % mod + 1) % mod;
	printf("%d\n",ans);
}

詳細信息

Test #1:

score: 10
Accepted
time: 6ms
memory: 10216kb

input:

5
1 1
1 2
1 3
1 4
2 1
3 1
3 2
3 3
3 4
5 1
5 2
5 3
5 4

output:

570425346

result:

ok single line: '570425346'

Test #2:

score: 10
Accepted
time: 5ms
memory: 10296kb

input:

5
1 3
2 4
4 3
5 3
3 1
5 4
4 2
1 4
4 4
3 3
3 2
1 1
2 2

output:

713031682

result:

ok single line: '713031682'

Test #3:

score: 10
Accepted
time: 7ms
memory: 10308kb

input:

13
1 3
12 1
12 2
1 4
13 3
13 2
3 2
13 1
1 1
3 4
3 3
1 2
12 3

output:

868236068

result:

ok single line: '868236068'

Test #4:

score: 10
Accepted
time: 4ms
memory: 10136kb

input:

13
1 1
13 1
2 3
1 3
3 1
3 4
2 1
13 4
1 4
12 2
13 3
12 3
3 2

output:

234399821

result:

ok single line: '234399821'

Test #5:

score: 10
Accepted
time: 11ms
memory: 10296kb

input:

13
2 3
2 1
12 2
13 2
2 2
1 2
13 3
12 4
13 4
3 4
3 1
12 3
1 3

output:

892522858

result:

ok single line: '892522858'

Test #6:

score: 10
Accepted
time: 41ms
memory: 10196kb

input:

81
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
11 1
12 1
13 1

output:

152635587

result:

ok single line: '152635587'

Test #7:

score: 10
Accepted
time: 43ms
memory: 10296kb

input:

94
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
11 1
12 1
13 1

output:

339459976

result:

ok single line: '339459976'

Test #8:

score: 10
Accepted
time: 49ms
memory: 10144kb

input:

96
1 2
1 3
1 4
1 1
2 2
2 3
2 4
2 1
3 2
3 3
3 4
3 1
4 2

output:

230028597

result:

ok single line: '230028597'

Test #9:

score: 10
Accepted
time: 43ms
memory: 10220kb

input:

83
1 2
1 3
1 4
1 1
2 2
2 3
2 4
2 1
3 2
3 3
3 4
3 1
4 2

output:

967250236

result:

ok single line: '967250236'

Test #10:

score: 10
Accepted
time: 114ms
memory: 10308kb

input:

100
67 1
26 4
12 4
11 4
30 4
29 1
1 4
13 3
30 1
64 2
63 1
20 2
32 4

output:

345132636

result:

ok single line: '345132636'

Extra Test:

score: 0
Extra Test Passed