QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#290656#5495. 寿司晚宴MoRanSky100 ✓134ms6936kbC++231.9kb2023-12-25 06:18:542023-12-25 06:18:55

Judging History

你现在查看的是最新测评结果

  • [2023-12-25 06:18:55]
  • 评测
  • 测评结果:100
  • 用时:134ms
  • 内存:6936kb
  • [2023-12-25 06:18:54]
  • 提交

answer

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
typedef long long LL;

using namespace std;

const int N = 505;

int n, m = 256, w[20], st[N];

LL P, f[N][N], g[N][N], h[N], c[N];

vector<int> e[N];

LL mul(LL a, LL b) {
	a %= P, b %= P;
	return ((a * b - (LL)((long double)a * b / P) * P) % P + P) % P;
}

int main() {
	w[2] = 0, w[3] = 1, w[5] = 2, w[7] = 3;
	w[11] = 4, w[13] = 5, w[17] = 6, w[19] = 7;
	scanf("%d%lld", &n, &P);
	f[0][0] = 1;
	for (int i = 2; i <= n; i++) {
		int x = i, s = 0, t = 0;
		for (int j = 2; j <= x; j++) {
			if (x % j == 0) {
				if (j <= 19) s |= 1 << w[j];
				else t = j;
				while (x % j == 0) x /= j;
			}
		}
		if (t) e[t].push_back(i), st[i] = s;
		else {
			memcpy(g, f, sizeof g);
			for (int u = m - 1; ~u; u--) {
				for (int v = m - 1; ~v; v--) {
					if ((u & v) || !g[u][v]) continue;
					if (((u | s) & v) == 0) (f[u | s][v] += g[u][v]) %= P;
					if ((u & (v | s)) == 0) (f[u][v | s] += g[u][v]) %= P;
				}
			}
		}
	}
	

	for (int i = 2; i <= n; i++) {
		if (!e[i].size()) continue; 
		memcpy(g, f, sizeof g);
		memset(h, 0, sizeof h);
		h[0] = 1;
		for (int j = 0; j < e[i].size(); j++) {
			int s = st[e[i][j]];
			memcpy(c, h, sizeof c);
			for (int k = m - 1; ~k; k--)
				(h[k | s] += c[k]) %= P;
		}

		h[0] = (h[0] + P - 1) % P;  
		for (int s = 0; s < m; s++) {
			if (!h[s]) continue;
			for (int u = m - 1; ~u; u--) {
				for (int v = m - 1; ~v; v--) {
					if ((u & v)) continue;
					if (((u | s) & v) == 0) f[u | s][v] = (f[u | s][v] + mul(g[u][v], h[s])) % P;
					if (((v | s) & u) == 0) f[u][v | s] = (f[u][v | s] + mul(g[u][v], h[s])) % P;
				}
			}
		}
	}	

	

	
	LL ans = 0;
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < m; j++) {
			if (!(i & j)) {
				(ans += f[i][j]) %= P;
			}
		}
	}
	
	printf("%lld\n", ans);
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 10
Accepted
time: 1ms
memory: 5988kb

input:

2 1

output:

0

result:

ok single line: '0'

Test #2:

score: 10
Accepted
time: 0ms
memory: 6168kb

input:

13 12345

output:

3438

result:

ok single line: '3438'

Test #3:

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

input:

26 1000000000

output:

447212583

result:

ok single line: '447212583'

Test #4:

score: 10
Accepted
time: 15ms
memory: 6872kb

input:

99 90000001

output:

88114119

result:

ok single line: '88114119'

Test #5:

score: 10
Accepted
time: 9ms
memory: 6756kb

input:

50 19999991

output:

16185855

result:

ok single line: '16185855'

Test #6:

score: 10
Accepted
time: 26ms
memory: 6936kb

input:

144 1000000000

output:

108118957

result:

ok single line: '108118957'

Test #7:

score: 10
Accepted
time: 37ms
memory: 6804kb

input:

197 1200007

output:

132550

result:

ok single line: '132550'

Test #8:

score: 10
Accepted
time: 54ms
memory: 6872kb

input:

289 1200007

output:

1181263

result:

ok single line: '1181263'

Test #9:

score: 10
Accepted
time: 76ms
memory: 6872kb

input:

362 99991111

output:

81393435

result:

ok single line: '81393435'

Test #10:

score: 10
Accepted
time: 134ms
memory: 6852kb

input:

499 99999999

output:

7282170

result:

ok single line: '7282170'

Extra Test:

score: 0
Extra Test Passed