This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#include "vision.h"
using namespace std;
//-1 = FALSE, -2 = TRUE
const int B = 15;
int my_add_or(vector <int> v) {
vector <int> tmp;
for (auto it : v)
if (it >= 0)
tmp.push_back(it);
else if (it == -2)
return -2;
return tmp.empty() ? -1 : add_or(tmp);
}
int my_add_and(vector <int> v) {
vector <int> tmp;
for (auto it : v)
if (it >= 0)
tmp.push_back(it);
else if (it == -1)
return -1;
return tmp.empty() ? -2 : add_and(tmp);
}
int my_add_not(int x) {
if (x < 0)
return -3 - x;
return add_not(x);
}
int my_add_nor(vector <int> v) {
return my_add_not(my_add_or(v));
}
vector <int> solve(vector <int> a) {
int N = a.size();
vector <vector <int>> pref(B);
for (int i = 0; i < N; i++)
pref[i % B].push_back(i < B ? a[i] : my_add_or({pref[i % B].back(), a[i]}));
vector <int> inv;
vector <vector <int>> residue_pair(B, vector <int> (B));
for (int i = 0; i < B; i++)
for (int j = 0; j < B; j++)
if (i != j) {
int cnt = 0;
vector <int> tmp;
for (int k = 0; k < N; k++) {
if (k % B == j && cnt)
tmp.push_back(my_add_and({pref[i][cnt - 1], a[k]}));
if (k % B == i)
cnt++;
}
residue_pair[i][j] = my_add_or(tmp);
if (i > j)
inv.push_back(residue_pair[i][j]);
}
for (int i = 0; i < B; i++) {
vector <int> tmp;
for (int j = 0; j < B; j++)
if (j != i && !pref[j].empty())
tmp.push_back(pref[j].back());
residue_pair[i][i] = my_add_nor(tmp);
}
vector <int> block(B);
for (int i = 0; i < B; i++) {
vector <int> tmp;
for (int j = 0; j < B; j++)
if (i * B + j < N)
tmp.push_back(a[i * B + j]);
block[i] = my_add_or(tmp);
}
vector <vector <int>> block_pair(B, vector <int> (B));
for (int i = 0; i < B - 1; i++)
for (int j = i + 1; j < B; j++)
block_pair[i][j] = my_add_and({block[i], block[j]});
for (int i = 0; i < B; i++) {
vector <int> tmp;
for (int j = 0; j < B; j++)
if (j != i)
tmp.push_back(block[j]);
block_pair[i][i] = my_add_nor(tmp);
}
int carry = my_add_or(inv);
int no_carry = my_add_not(carry);
vector <int> residue_diff(B);
for (int i = 0; i < B; i++) {
vector <int> tmp;
for (int j = 0; j < B; j++)
tmp.push_back(residue_pair[j][(i + j) % B]);
residue_diff[i] = my_add_or(tmp);
}
vector <int> block_diff(B);
for (int i = 0; i < B; i++) {
vector <int> option1, option2;
for (int j = 0; j < B - i; j++) {
option1.push_back(block_pair[j][i + j]);
if (j < B - i - 1)
option2.push_back(block_pair[j][i + j + 1]);
}
block_diff[i] = my_add_or({my_add_and({my_add_or(option1), no_carry}), my_add_and({my_add_or(option2), carry})});
}
vector <int> res(N);
for (int i = 0; i < N; i++)
res[i] = my_add_and({block_diff[i / B], residue_diff[i % B]});
return res;
}
void construct_network(int H, int W, int K) {
vector <int> row(H);
for (int i = 0; i < H; i++) {
vector <int> tmp(W);
for (int j = 0; j < W; j++)
tmp[j] = i * W + j;
row[i] = my_add_or(tmp);
}
vector <int> col(W);
for (int j = 0; j < W; j++) {
vector <int> tmp(H);
for (int i = 0; i < H; i++)
tmp[i] = i * W + j;
col[j] = my_add_or(tmp);
}
vector <int> combs;
vector <int> row_diff = solve(row);
vector <int> col_diff = solve(col);
for (int i = 0; i <= K; i++)
if (i < H && K - i < W)
combs.push_back(my_add_and({row_diff[i], col_diff[K - i]}));
my_add_or(combs);
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |