QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#153485 | #5442. Referee Without Red | syksykCCC | WA | 24ms | 59040kb | C++14 | 3.9kb | 2023-08-30 08:05:04 | 2023-08-30 08:05:05 |
Judging History
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'