Submission #48560

#TimeUsernameProblemLanguageResultExecution timeMemory
48560ngkan146Library (JOI18_library)C++14
100 / 100
513 ms4968 KiB
#include <bits/stdc++.h> #include "library.h" using namespace std; int cnt[1005][10]; // if bit x off -> insert i, else erase i vector <int> askBitAll[10]; int cntAll[10], cntNum[10]; vector <int> G[1005]; vector <int> ans; int cntMask[1024]; int cntnumMask[1024]; vector <int> askMask[1024]; void dfs(int u,int p){ ans.push_back(u); for(auto v: G[u]){ if (v == p) continue; dfs(v, u); } } void Solve(int n){ if (n == 1){ ans.push_back(1); Answer(ans); return; } // build askMask for(int mask=0;mask<1024;mask++){ askMask[mask].assign(n, 0); for(int i=1;i<=n;i++) cntnumMask[mask] += (i & mask) == mask, askMask[mask][i-1] = ((i & mask) == mask); if (cntnumMask[mask]) cntMask[mask] = Query(askMask[mask]); } // build cnt all for(int bit=0;bit<10;bit++){ askBitAll[bit].assign(n, 0); for(int j=1;j<=n;j++) cntNum[bit] += ((j>>bit)&1), askBitAll[bit][j-1] = ((j>>bit)&1); if (cntNum[bit]) cntAll[bit] = Query(askBitAll[bit]); } // ask n * log times, prep cnt for(int i=1;i<=n;i++){ for(int bit=0;bit<10;bit++){ if (((i>>bit)&1) == 1) cntNum[bit] --; else cntNum[bit] ++; askBitAll[bit][i-1] ^= 1; if (cntNum[bit]) cnt[i][bit] = Query(askBitAll[bit]); askBitAll[bit][i-1] ^= 1; if (((i>>bit)&1) == 1) cntNum[bit] ++; else cntNum[bit] --; } } // find adj of i in log times for(int i=1;i<=n;i++){ int mask = 0; int okBit = 0; for(int bit=0;bit<10;bit++){ if (((i>>bit)&1) == 0){ // don't have bit, try to insert if (cntAll[bit] - cnt[i][bit] == -1){ okBit |= (1<<bit); } else if (cntAll[bit] == cnt[i][bit]){ // hmm } else{ okBit |= (1<<bit); mask += (1<<bit); } } else{ // have bit, try to remove if (cntAll[bit] - cnt[i][bit] == 1){ okBit |= (1<<bit); } else if (cntAll[bit] == cnt[i][bit]){ // hmm } else{ okBit |= (1<<bit); mask += (1<<bit); } } } //cout << i << ' '<< mask << ' ' << okBit << endl; int firstAdj = mask, secondAdj = mask; for(int bit=0;bit<10;bit++){ //cout << i << ' ' << bit << endl; if (((okBit>>bit)&1) == 1) continue; if (firstAdj + (1<<bit) > n){ secondAdj += (1<<bit); continue; } if (secondAdj + (1<<bit) > n){ firstAdj += (1<<bit); continue; } //cout << "process " << ' ' << bit << endl; int finalMask = firstAdj + (1<<bit); if ((i & finalMask) == finalMask){ askMask[finalMask][i-1] = 0; int ask = (cntnumMask[finalMask] == 1 ? 0 : Query(askMask[finalMask])); if (cntMask[finalMask] - ask == 1) secondAdj += (1<<bit); else firstAdj += (1<<bit); askMask[finalMask][i-1] = 1; } else{ askMask[finalMask][i-1] = 1; int ask = Query(askMask[finalMask]); if (cntMask[finalMask] - ask == -1) secondAdj += (1<<bit); else firstAdj += (1<<bit); askMask[finalMask][i-1] = 0; } } //cout << i << ' ' << firstAdj << ' ' << secondAdj << endl; if (firstAdj) G[i].push_back(firstAdj); if (secondAdj) G[i].push_back(secondAdj); } for(int i=1;i<=n;i++){ if (G[i].size() == 1){ dfs(i, i); break; } } Answer(ans); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...