Submission #1283199

#TimeUsernameProblemLanguageResultExecution timeMemory
1283199MMihalevSphinx's Riddle (IOI24_sphinx)C++20
28.50 / 100
81 ms1204 KiB
#include<iostream> #include<vector> #include<cstring> #include<algorithm> #include<set> #include<random> #include "sphinx.h" //#include "grader.cpp" using namespace std; const int MAX_N=252; int n; vector<int>g[MAX_N]; vector<int>exp1,ans; set<int>idseven,idsodd; int cols[MAX_N]; vector<int>dif; int queryN[2][MAX_N][MAX_N]; int query[2][MAX_N][MAX_N]; bool used[MAX_N]; int depth[MAX_N]; bool init=1; void dfs(int u) { used[u]=1; for(int v:g[u]) { if(used[v] or cols[v]==0)continue; if(init)depth[v]=depth[u]+1; dfs(v); } } int comps() { int cmps=0; for(int i=0;i<n;i++)used[i]=0; for(int i=0;i<n;i++) { if(!used[i] && cols[i]) { cmps++; dfs(i); } } return cmps; } bool check(bool wh,int l,int r,set<int>ids,int col) { bool full=1; for(int id:ids) { if(ans[id]==-1)full=0; } if(full)return 0; if(ids.size()==1) { for(int i=0;i<n;i++)exp1[i]=col; exp1[(*(ids.begin()))]=-1; if(perform_experiment(exp1)==1) { return 1; } return 0; } for(int i=0;i<n;i++)exp1[i]=col; for(int id:ids) { if(ans[id]==-1)exp1[id]=-1; } if(query[wh][l][r]==-1) { query[wh][l][r]=perform_experiment(exp1); } int cnt=query[wh][l][r]; if(queryN[wh][l][r]<=-1) { int x=-1-queryN[wh][l][r]; vector<int>exp2;exp2.resize(n); for(int i=0;i<n;i++)exp2[i]=n; for(int id:ids)exp2[id]=-1; queryN[wh][l][r]=perform_experiment(exp2)-x; } int cntN=queryN[wh][l][r]; //cout<<"\n"; for(int id:ids) { //cout<<id<<" "<<ans[id]<<" "<<cnt<<" "<<cntN<<" "<<col<<"\n"; } //cout<<"\n"; if(cnt<cntN)return 1; return 0; } set<int>tmp; void colour(bool wh,int l,int r,set<int>ids,int u,int col) { ans[u]=col; bool full=1; for(int id:ids) { if(ans[id]==-1)full=0; } if(full) { vector<int>tocolour; for(int v:g[u]) { if(dif[v]==dif[u] && ans[v]==-1) { if((depth[v]%2==0 && wh==0) or (depth[v]%2==1 && wh==1)) { tocolour.push_back(v); } else tmp.insert(v); } } for(int v:tocolour) { if(ans[v]!=-1)continue; set<int>idsreal; if(wh==0)idsreal=idseven; else idsreal=idsodd; colour(wh,0,idsreal.size()-1,idsreal,v,col); } return; } int uni=1; for(int v:g[u]) { if(ans[v]==-1 && ids.count(v) && dif[v]==dif[u]) { uni=0; break; } } for(int i=0;i<n;i++) { cols[i]=1; } for(int id:ids) { if(ans[id]==-1)cols[id]=0; } cols[u]=0; int diff=comps(); cols[u]=1; diff=diff-comps(); queryN[wh][l][r]-=(uni+diff); int mid=(ids.size()-1)/2; vector<int>idd; for(int id:ids)idd.push_back(id); set<int>ids1,ids2; for(int i=0;i<ids.size();i++) { if(i<=mid)ids1.insert(idd[i]); else ids2.insert(idd[i]); } mid=(l+r)/2; if(ids1.count(u))colour(wh,l,mid,ids1,u,col); else colour(wh,mid+1,r,ids2,u,col); } void rec(bool wh,int l,int r,set<int>ids,int col) { if(ids.size()==1) { set<int>idsreal; if(wh==0)idsreal=idseven; else idsreal=idsodd; colour(wh,0,idsreal.size()-1,idsreal,(*(ids.begin())),col); return; } int mid=(ids.size()-1)/2; vector<int>idd; for(int id:ids)idd.push_back(id); set<int>ids1,ids2; for(int i=0;i<ids.size();i++) { if(i<=mid)ids1.insert(idd[i]); else ids2.insert(idd[i]); } mid=(l+r)/2; bool full=1; for(int id:ids1) { if(ans[id]==-1)full=0; } if(full){rec(wh,mid+1,r,ids2,col);return;} full=1; for(int id:ids2) { if(ans[id]==-1)full=0; } if(full){rec(wh,l,mid,ids1,col);return;} if(check(wh,l,mid,ids1,col))rec(wh,l,mid,ids1,col); else rec(wh,mid+1,r,ids2,col); } vector<vector<int>>nodescol; vector<int>uniq; int all; bool alone(int l,int r,int i) { for(int u=0;u<n;u++){cols[u]=1;exp1[u]=n;} cols[i]=0; exp1[i]=-1; for(int c=l;c<=r;c++) { for(int u:nodescol[uniq[c]]) { cols[u]=0; exp1[u]=-1; } } int cmps=comps()+(r-l+1)+1; int x=perform_experiment(exp1); if(all==-1)all=cmps-x; if(x<cmps)return 0; return 1; } void different() { for(int i=1;i<n;i++) { nodescol.clear(); nodescol.resize(n); uniq.clear(); for(int v:g[i]) { if(v<i) { if(nodescol[dif[v]].size()==0) { uniq.push_back(dif[v]); } nodescol[dif[v]].push_back(v); } } int l=0,r=uniq.size()-1; all=-1; if(alone(l,r,i)) { dif[i]=i; continue; } int firsteq=-1; vector<int>allnodes; allnodes.push_back(i); while(all--) { while(l<r) { int mid=(l+r)/2; if(alone(l,mid,i)) { l=mid+1; } else { r=mid; } } for(int u:nodescol[uniq[l]])allnodes.push_back(u); if(firsteq==-1)firsteq=l; l++; r=uniq.size()-1; } for(int u:allnodes) { dif[u]=uniq[firsteq]; } } } std::vector<int> find_colours(int N, std::vector<int> X, std::vector<int> Y) { n=N; exp1.resize(n);ans.resize(n);dif.resize(n); for(int i=0;i<n;i++){cols[i]=1;ans[i]=-1;} for(int i=0;i<X.size();i++) { g[X[i]].push_back(Y[i]); g[Y[i]].push_back(X[i]); } dfs(0); init=0; different();return dif; for(int i=0;i<n;i++) { for(int j=i;j<n;j++) { queryN[0][i][j]=-1; queryN[1][i][j]=-1; } } for(int i=0;i<n;i++) { if(ans[i]==-1 && depth[i]%2==0)idseven.insert(i); } for(int i=0;i<n;i++) { if(ans[i]==-1 && depth[i]%2==1)idsodd.insert(i); } for(int col=0;col<n;col++) { for(int i=0;i<n;i++) { for(int j=i;j<n;j++) { query[0][i][j]=-1; query[1][i][j]=-1; } } tmp.clear(); while(1) { bool full=1; for(int id:idseven) { if(ans[id]==-1)full=0; } if(full)break; if(check(0,0,idseven.size()-1,idseven,col))rec(0,0,idseven.size()-1,idseven,col); else break; } for(int u:tmp) { if(ans[u]==-1)colour(1,0,idsodd.size()-1,idsodd,u,col); } while(1) { bool full=1; for(int id:idsodd) { if(ans[id]==-1)full=0; } if(full)break; if(check(1,0,idsodd.size()-1,idsodd,col))rec(1,0,idsodd.size()-1,idsodd,col); else break; } } return ans; }
#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...