Submission #650049

#TimeUsernameProblemLanguageResultExecution timeMemory
650049esomerUnscrambling a Messy Bug (IOI16_messy)C++17
100 / 100
4 ms480 KiB
#include <bits/stdc++.h> #include "messy.h" using namespace std; #define ll long long //#define endl "\n" const int MOD = 998244353; int added = 0; int checked = 0; /*void add_element(string x); void compile_set(); bool check_element(string x);*/ bool checkk_element(string &s){ if(checked == 896){ cout << "CHECKS TOO MUCH"<< endl; exit(0); } checked++; bool rep = check_element(s); return rep; } void addd_element(string& s){ if(added == 896){ cout << "ADDS TOO MUCH"<< endl; exit(0); } added++; add_element(s); } void add_lg(int n, int lg){ string s = ""; for(int i = 0; i < n; i++) s += '0'; s[0] = '1'; s[1] = '1'; addd_element(s); s[1] = '0'; s[2] = '1'; s[3] = '1'; addd_element(s); s[1] = '1'; s[2] = '0'; s[3] = '0'; for(int i = 2; i < lg; i++){ s[i] = '1'; addd_element(s); } } void check_lg(int n, int lg, vector<int>& possible, vector<int>& ind){ string s = ""; for(int i = 0; i < n; i++) s += '0'; pair<int, int> initial = {-1, -1}; for(int i = 0; i < lg && initial.first == -1; i++){ for(int j = i + 1; j < lg && initial.first == -1; j++){ for(int q = 0; q < lg; q++) s[possible[q]] = '0'; s[possible[i]] = '1'; s[possible[j]] = '1'; //cout << "S: "<< s << endl; bool rep = checkk_element(s); if(rep){ initial = {possible[i], possible[j]}; } } } //cout << "Initital.first" << initial.first << " "<< initial.second << endl; for(int i = 2; i < lg; i++){ for(int j = 0; j < lg; j++){ for(int q = 0; q < lg; q++) s[possible[q]] = '0'; for(int q = i - 1; q >= 2; q--) s[ind[q]] = '1'; s[initial.first] = '1'; s[initial.second] = '1'; if(s[possible[j]] == '1') continue; else if(i == lg - 1){ for(int x : possible){ if(s[x] == '0') ind[i] = x; } break; } s[possible[j]] = '1'; //cout << "S: "<< s << endl; bool rep = checkk_element(s); if(rep){ ind[i] = possible[j]; break; } } } for(int q = 0; q < lg; q++) s[possible[q]] = '0'; s[initial.first] = '1'; s[ind[2]] = '1'; s[ind[3]] = '1'; bool rep = checkk_element(s); if(rep) {ind[0] = initial.first; ind[1] = initial.second;} else {ind[1] = initial.first; ind[0] = initial.second;} } vector<int> restore_permutation(int n, int w, int r){ if(n == 8){ string s = ""; for(int i = 0; i < n; i++) s += '0'; for(int i = 0; i < n; i++){ s[i] = '1'; addd_element(s); } compile_set(); vector<int> ans(n, -1); for(int i = 0; i < n; i++){ for(int j = 0; j < n; j++){ if(ans[j] != -1) continue; s = ""; for(int q = 0; q < n; q++){ if(ans[q] != -1) s += '1'; else s += '0'; } s[j] = '1'; bool rep = checkk_element(s); if(rep){ ans[j] = i; break; } } } return ans; } int lg = 0; int curr = 1; while(curr < n){ lg++; curr *= 2; } vector<vector<int>> v(n, vector<int>(lg, -1)); int num = n / 2; int d = 4; map<vector<int>, int> should; for(int k = 0; k < lg; k++){ int have = 1; curr = 0; //cout << "K "<< k << " num "<< num << endl; for(int i = 0; i < n; i++){ if(curr == num) {curr = 0; have = 1 - have;} if(i < lg){curr++; continue;} //cout << "" if(have == 1) should[v[i]]++; v[i][k] = have; curr++; } num = n / d; d *= 2; } for(int i = lg; i < n; i++){ string s = ""; for(int j = 0; j < n; j++) s += '0'; s[i] = '1'; addd_element(s); for(int j = 0; j < lg; j++){ if(v[i][j]) s[j] = '1'; if(v[i][j]) addd_element(s); } } add_lg(n, lg); compile_set(); vector<vector<int>> reconstruct(n, vector<int>(lg, -1)); vector<int> ind(lg); vector<int> possible; vector<bool> possible1(n, 0); for(int i = 0; i < n; i++){ string s = ""; for(int j = 0; j < n; j++) s += '0'; s[i] = '1'; bool rep = checkk_element(s); if(!rep) {possible.push_back(i); possible1[i] = 1;} } check_lg(n, lg, possible, ind); /*cout << "Possible "<< endl; for(int x : possible) cout << x << " "; cout << endl << "Ind "<< endl; for(int i = 0; i < lg; i++){ cout << "I: "<< i << " ind "<< ind[i] << endl; }*/ map<vector<int>, int> have; for(int k = 0; k < lg; k++){ map<vector<int>, int> ones; map<vector<int>, int> asked; for(int i = 0; i < n; i++){ if(possible1[i]) continue; if(asked[reconstruct[i]] + 1 == have[reconstruct[i]] && k > 0){ if(ones[reconstruct[i]] != should[reconstruct[i]]) reconstruct[i][k] = 1; else reconstruct[i][k] = 0; continue; } string s = ""; for(int j = 0; j < n; j++) s += '0'; s[i] = '1'; for(int j = 0; j < k; j++){ if(reconstruct[i][j] == 1) s[ind[j]] = '1'; } s[ind[k]] = '1'; asked[reconstruct[i]]++; bool rep = checkk_element(s); if(rep) {ones[reconstruct[i]]++; reconstruct[i][k] = 1;} else reconstruct[i][k] = 0; } have.clear(); ones.clear(); asked.clear(); for(int i = 0; i < n; i++){ have[reconstruct[i]]++; } } /*for(int i = lg; i < n; i++){ cout << "V[i] "<<i<< endl; for(auto x : v[i]) cout << x << " "; cout << endl; } for(int i = 0; i < n; i++){ cout << "Reconstruct[i] "<<i<< endl; for(auto x : reconstruct[i]) cout << x << " "; cout << endl; }*/ vector<int> ans(n); for(int i = 0; i < n; i++){ if(possible1[i]){ for(int j = 0; j < lg; j++){ if(ind[j] == i) ans[i] = j; } }else{ for(int j = 0; j < n; j++){ if(reconstruct[i] == v[j]) ans[i] = j; } } /*cout << "Reconstruct i "<< i << endl; for(auto x : reconstruct[i]) cout << x << " "; cout << endl;*/ } return ans; } /* namespace helper { set<string> set_; bool compiled = false; int n; vector<int> p; int w; int r; int read_int() { int x; cin >> x; return x; } } using namespace helper; // A convenience function. int get_p(int i) { int ret = p[i]; return ret; } mt19937 gen(time(0)); int main() { for(int times = 0; times < 100; times++){ n = 128; w = 896; r = 896; checked = 0; added = 0; compiled = false; set_.clear(); p = vector<int>(n); vector<int> possible(n); for(int i = 0; i < n; i++) possible[i] = i; for (int i = 0; i < n; i++) { int sz = (int)possible.size(); int ind = gen() % sz; p[i] = possible[ind]; vector<int> v = possible; possible.clear(); for(int x : v){ if(x == p[i]) continue; possible.push_back(x); } } vector<int> answer = restore_permutation(n, w, r); if (answer.size() != n) { printf("WA\n"); cout << "P" << endl; for(int x : p) cout << x << " "; cout << endl << "Ans"<<endl; for(int x : answer) cout << x << " "; cout << endl; return 0; } vector<bool> found(n, 0); for(int i = 0; i < n; i++){ if(found[p[i]]){ cout << "REPEATS"<< endl; return 0; } found[p[i]] = 1; } for(int i = 0; i < n; i++){ if(answer[i] != p[i]){ cout << "P" << endl; for(int x : p) cout << x << " "; cout << endl << "Ans"<<endl; for(int x : answer) cout << x << " "; cout << endl; return 0; } } printf("%d", answer[0]); for (int i = 1; i < n; i++) { printf(" %d", answer[i]); } printf("\n"); return 0; } cout << "Good"<< endl; } void wa() { printf("WA\n"); exit(0); } bool check(const string& x) { if ((int)x.length() != n) { return false; } for (int i = 0; i < n; i++) { if (x[i] != '0' && x[i] != '1') { return false; } } return true; } void add_element(string x) { if (--w < 0 || compiled || !check(x)) { //wa(); cout << "Error adding" << endl; } set_.insert(x); } bool check_element(string x) { if (--r < 0 || !compiled || !check(x)) { //wa(); cout << "Error checking"<< endl; } return set_.count(x); } void compile_set() { if (compiled) { //wa(); cout << "Error compiling"<<endl; } compiled = true; set<string> compiledSet; string compiledElement = string(n, ' '); for (set<string>::iterator it = set_.begin(); it != set_.end(); it++) { string s = *it; for (int i = 0; i < n; i++) { compiledElement[i] = s[get_p(i)]; } compiledSet.insert(compiledElement); } set_ = compiledSet; } */
#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...