Submission #541641

#TimeUsernameProblemLanguageResultExecution timeMemory
541641abekerVision Program (IOI19_vision)C++17
100 / 100
18 ms1772 KiB
#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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...