Submission #1154482

#TimeUsernameProblemLanguageResultExecution timeMemory
1154482salmonToxic Gene (NOI23_toxic)C++20
100 / 100
14 ms328 KiB
#include "toxic.h" #include <bits/stdc++.h> using namespace std; char type[301]; vector<int> v; vector<int> pro; vector<int> trans; vector<vector<int>> segregate(vector<int> v, int n, int l){ vector<vector<int>> ans; int cont = 0; for(int i = 0; i < n ; i++){ if(cont == v.size()) break; vector<int> temp; for(int j = 0; j < l; j++){ if(cont == v.size()) break; temp.push_back(v[cont]); cont++; } ans.push_back(temp); } return ans; } int fquery(vector<int> v){ for(int i = 0; i < v.size(); i++){ v[i] = trans[v[i]]; } return query_sample(v); } int squery(vector<int> v){ vector<int> sas; vector<int> ind; int sise = v.size(); int two = 1; while(!pro.empty() && v.size() + two <= 300){ //printf("%d %d %d\n",pro.size(),fquery(v),v.size()); if(type[pro.back()] != 0){ pro.pop_back(); continue; } sas.push_back(two); two *= 2; ind.push_back(pro.back()); pro.pop_back(); for(int i = 0; i < sas.back(); i++){ v.push_back(ind.back()); } } int num = fquery(v); if(num != v.size()){ while(!ind.empty()){ if(num >= sas.back()){ num -= sas.back(); type[ind.back()] = 'S'; } else{ type[ind.back()] = 'R'; } sas.pop_back(); ind.pop_back(); } } else{ for(int j : ind) pro.push_back(j); return sise; } return num; } int oquery(vector<int> v){ vector<int> sas; vector<int> ind; int sise = v.size(); while(!pro.empty() && v.size() + v.size() <= 300){ //printf("%d %d %d\n",pro.size(),fquery(v),v.size()); if(type[pro.back()] != 0){ pro.pop_back(); continue; } sas.push_back(v.size()); ind.push_back(pro.back()); pro.pop_back(); for(int i = 0; i < sas.back(); i++){ v.push_back(ind.back()); } } int num = fquery(v); if(num != v.size()){ while(!ind.empty()){ if(num >= sas.back()){ num -= sas.back(); type[ind.back()] = 'S'; } else{ type[ind.back()] = 'R'; } sas.pop_back(); ind.pop_back(); } } else{ for(int j : ind) pro.push_back(j); return sise; } return num; } int iquery(vector<int> v){ vector<int> ind; vector<int> sas; int num = 0; int N = v.size(); int sise = N; for(int i = 1; i < N; i++){ int cont = (N-i); for(int j = 0; j < i; j++){ cont = cont * 2 + 1; } if( cont > 300){ break; } num = i; } ind.push_back(v[0]); sas.push_back(1); for(int i = 0; i < num; i++){ ind.push_back(v.back()); v.pop_back(); } for(int i = 1; i <= num; i++){ sas.push_back(v.size() + 1); for(int j = 0; j < sas.back(); j++){ v.push_back(ind[i]); } } num = oquery(v); if(num != v.size()){ while(!ind.empty()){ if(num >= sas.back()){ num -= sas.back(); type[ind.back()] = 'S'; } else{ type[ind.back()] = 'R'; } sas.pop_back(); ind.pop_back(); } return 0; } else{ return sise; } } void findtoxicsub(vector<int> ve, int t){ /*if(squery(ve) == ve.size()){ for(int i : ve){ pro.push_back(i); } return; }*/ if(ve.size() == 1){ if(squery(ve) == 0) type[ve[0]] = 'T'; return; } if(t > ve.size()){ t = ve.size(); } int past = ve.size(); int num = (ve.size() + 1)/2 ; int two = 1; while(num >= t && num > 1){ two = two * 2; past = num; num = (num + 1)/2; } vector<vector<int>> pros = segregate(ve,past,two); vector<vector<int>> next; vector<int> ukown; for(int i = 0; i < pros.size(); i++){ if(squery(pros[i]) != pros[i].size()){ next.push_back(pros[i]); } else{ for(int j : pros[i]){ pro.push_back(j); } } } while(next.size() != 0){ swap(pros,next); next.clear(); for(int i = 0; i < pros.size(); i++){ vector<int> temp; for(int j: pros[i]){ if(type[j] != 'S') temp.push_back(j); } pros[i] = temp; temp.clear(); if(pros[i].size() == 0){ t++; t--; } else if(pros[i].size() == 1){ t--; type[pros[i][0]] = 'T'; } else{ for(int j = 0; j < pros[i].size()/2 ; j++){ temp.push_back(pros[i][j]); } if(squery(temp) == temp.size()){ for(int i : temp){ pro.push_back(i); } temp.clear(); for(int j = pros[i].size()/2; j < pros[i].size(); j++){ temp.push_back(pros[i][j]); } next.push_back(temp); } else{ next.push_back(temp); for(int j = pros[i].size()/2; j < pros[i].size(); j++){ ukown.push_back(pros[i][j]); } } } } } if(!ukown.empty()) findtoxicsub(ukown,t); } void findtoxic(vector<int> ve, int t){ int past = ve.size(); int num = (ve.size() + 1)/2 ; int two = 1; while(num >= t && num > 1){ two = two * 2; past = num; num = (num + 1)/2; } vector<vector<int>> pros = segregate(ve,past,two); vector<vector<int>> next; vector<int> ukown; for(int i = 0; i < pros.size(); i++){ if(iquery(pros[i]) != pros[i].size()){ next.push_back(pros[i]); } else{ for(int j : pros[i]){ pro.push_back(j); } } } while(next.size() != 0){ swap(pros,next); next.clear(); for(int i = 0; i < pros.size(); i++){ vector<int> temp; for(int j: pros[i]){ if(type[j] != 'S') temp.push_back(j); } pros[i] = temp; temp.clear(); if(pros[i].size() == 0){ t++; t--; } else if(pros[i].size() == 1){ t--; type[pros[i][0]] = 'T'; } else{ for(int j = 0; j < pros[i].size()/2 ; j++){ temp.push_back(pros[i][j]); } if(squery(temp) == temp.size()){ for(int i : temp){ pro.push_back(i); } temp.clear(); for(int j = pros[i].size()/2; j < pros[i].size(); j++){ temp.push_back(pros[i][j]); } next.push_back(temp); } else{ next.push_back(temp); for(int j = pros[i].size()/2; j < pros[i].size(); j++){ ukown.push_back(pros[i][j]); } } } } } if(!ukown.empty()) findtoxicsub(ukown,t); } void determine_type(int n){ v.clear(); trans.clear(); trans.push_back(0); for(int i = 1; i <= n; i++){ type[i] = 0; v.push_back(i); trans.push_back(i); } random_shuffle ( trans.begin() + 1, trans.end()); random_shuffle ( trans.begin() + 1, trans.end()); random_shuffle ( trans.begin() + 1, trans.end()); pro.clear(); findtoxic(v,30); int p; for(int i = 1; i <= n; i++){ if(type[i] == 'T'){ p = i; } } v.clear(); while(!pro.empty()){ if(type[pro.back()] != 0){ pro.pop_back(); } squery(vector<int>{p}); } for(int i = 1; i <= n; i++){ answer_type(trans[i], type[i]); } }
#Verdict Execution timeMemoryGrader output
Fetching results...