QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#153485#5442. Referee Without RedsyksykCCCWA 24ms59040kbC++143.9kb2023-08-30 08:05:042023-08-30 08:05:05

Judging History

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

  • [2023-08-30 08:05:05]
  • 评测
  • 测评结果:WA
  • 用时:24ms
  • 内存:59040kb
  • [2023-08-30 08:05:04]
  • 提交

answer

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

const int N = 1e6 + 5, MOD = 998244353, INV2 = (MOD + 1) / 2;
int fact[N * 3], ifact[N * 3];

namespace solve {

int n, m, perm[N], r[N], c[N], ans, tub[N * 3];
bool vis[N];
vector<int> a[N];
vector<pair<int, int>> R, C; // (size, start)

void init(int len, vector<pair<int, int>> &V, int id[N]) {
	for(int i = 1; i <= len; i++) {
		if(i & 1) {
			perm[i] = (i + 1) / 2;
		} else {
			perm[i] = i / 2 + (len + 1) / 2;
		}
	}
	V.clear();
	memset(vis, false, sizeof(bool) * (len + 1));
	id[0] = 0;
	for(int i = 1; i <= len; i++) {
		if(vis[i]) continue;
		int p = i, cnt = 0, beg = id[0] + 1;
		while(!vis[p]) {
			cnt++;
			vis[p] = true;
			id[++id[0]] = p;
			p = perm[p];
		}
		V.emplace_back(cnt, beg);
	}
}

int kmp(vector<int> &s) {
	int len = s.size() - 1;
	vector<int> nxt(s.size());
	nxt[1] = 0;
	int j = 0;
	for(int i = 1; i < len; i++) {
		while(j && s[j + 1] != s[i + 1]) j = nxt[j];
		if(s[j + 1] == s[i + 1]) {
			nxt[i + 1] = ++j;
		} else {
			nxt[i + 1] = 0;
		}
	}
	for(int i = nxt[len]; i; i = nxt[i]) {
		if(n % (n - i) == 0) return n - i;
	}
	// if(len % (len - nxt[len]) == 0) return len - nxt[len];
	return len;
}

struct disjoint_sets_union {
	int fa[N * 2];
	void init() {
		for(int i = 0; i <= R.size() + C.size(); i++) {
			fa[i] = i;
		}
	}
	int find(int p) {
		return fa[p] == p ? p : fa[p] = find(fa[p]);
	}
	void link(int u, int v) {
		u = find(u); v = find(v);
		if(u == v) return;
		fa[v] = u;
		ans = ans * 2 % MOD;  
	}
} dsu;

int main() {
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= n; i++) {
		a[i].resize(m + 1);
		for(int j = 1; j <= m; j++) {
			scanf("%d", &a[i][j]);
		}
	}
	init(n, R, r);
	init(m, C, c);
	ans = 1;

	for(int i = 0; i < R.size(); i++) {
		if(R[i].first == 1) {
			int cur = r[R[i].second], lcm = 1;
			for(int j = 0; j < C.size(); j++) {
				int len = C[j].first, beg = C[j].second;
				vector<int> str(1);
				for(int k = 0; k < len; k++) {
					str.emplace_back(a[cur][c[beg + k]]);
				}
				int res = kmp(str);
				lcm = lcm / __gcd(lcm, res) * res;
			}
			ans = (ll)ans * lcm % MOD;
		}
	}

	for(int i = 0; i < C.size(); i++) {
		if(C[i].first == 1) {
			int cur = c[C[i].second], lcm = 1;
			for(int j = 0; j < R.size(); j++) {
				int len = R[j].first, beg = R[j].second;
				vector<int> str(1);
				for(int k = 0; k < len; k++) {
					str.emplace_back(a[r[beg + k]][cur]);
				}
				int res = kmp(str);
				lcm = lcm / __gcd(lcm, res) * res;
			}
			ans = (ll)ans * lcm % MOD;
		}
	}

	dsu.init();
	for(int i = 0; i < R.size(); i++) {
		if(R[i].first == 1) continue;
		for(int j = 0; j < C.size(); j++) {
			if(C[j].first == 1) continue;
			vector<int> used;
			bool fre = false;
			for(int x = 0; x < R[i].first; x++) {
				for(int y = 0; y < C[j].first; y++) {
					int val = a[r[R[i].second + x]][c[C[j].second + y]];
					if(tub[val]) {
						fre = true;
					} else {
						used.emplace_back(val);
					}
					tub[val]++;
				}
			}
			ans = (ll)ans * fact[R[i].first * C[j].first] % MOD;
			for(int val : used) {
				ans = (ll)ans * ifact[tub[val]] % MOD;
				tub[val] = 0;
			}
			if(!fre) {
				ans = (ll)ans * INV2 % MOD;
				int u = R[i].first & 1 ? 0 : i + 1;
				int v = C[j].first & 1 ? 0 : R.size() + j + 1;
				dsu.link(u, v);
			}
			
		}
	}

	printf("%d\n", ans);

	return 0;
}

}

int qpow(int a, int p) {
	int res = 1;
	while(p) {
		if(p & 1) res = (ll)res * a % MOD;
		a = (ll)a * a % MOD;
		p >>= 1;
	}
	return res;
}

int main() {
	// freopen("1J1.in", "r", stdin);
	fact[0] = fact[1] = 1;
	for(int i = 2; i < 3 * N; i++) {
		fact[i] = (ll)fact[i - 1] * i % MOD;
	}
	ifact[3 * N - 1] = qpow(fact[3 * N - 1], MOD - 2);
	for(int i = 3 * N - 1; i; i--) {
		ifact[i - 1] = (ll)ifact[i] * i % MOD;
	}
	int T;
	scanf("%d", &T);
	while(T--) {
		solve::main();
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 24ms
memory: 59040kb

input:

2
4 4
1 2 3 4
3 4 1 2
1 2 4 1
4 3 3 2
3 9
1 8 1 1 8 1 1 8 1
1 8 8 8 8 8 8 8 1
1 1 1 8 8 8 1 1 1

output:

192
12672

result:

wrong answer 1st numbers differ - expected: '96', found: '192'