제출 #1251218

#제출 시각아이디문제언어결과실행 시간메모리
1251218model_codeMigrations (IOI25_migrations)C++20
100 / 100
35 ms1144 KiB
// solution/zein_Z4_M8.cpp // { // "verdict": "model_solution" // } // END HEADER #include "migrations.h" #include <bits/stdc++.h> using namespace std; typedef vector<int> vi; typedef pair<int,int> ii; struct Phase{ int m,b,k, start; bool tri; Phase(int _m, int _b,int _k, int _s, bool _tri): m(_m), b(_b), k(_k), start(_s), tri(_tri){} }; vector<Phase> phases; int Nglob; int pickB(int m) { int best_b = 1; int best_f = INT_MAX; int limit = (int)(2 * cbrt((double)(m+1))) + 2; for (int b = 1; b <= limit; ++b) { int term1 = (m + 1 + b - 1) / b; int term2 = ((b*b - 1) + 4 - 1) / 4; int f = term1 + term2 - 1; if (f < best_f) { best_f = f; best_b = b; } } return best_b; } int pickBFirst(int m){ int best_b=1, best_f=INT_MAX; int limit = 2*cbrt((double)(m+1))+2; for(int b=1;b<=limit;++b){ int t1 = (m+1 + b-1)/b; int states = b*(b+1)/2; int t2 = ((states-1) + 4-1)/4; int f = t1 + t2 - 1; if(f<best_f){ best_f=f; best_b=b; } } return best_b; } void calculateCandidates(vector<Phase>& phase) { for(int i=4;i<Nglob-3;++i){ phase.clear(); int m=i-1, pos=i-1; bool first = true; while(pos < Nglob-3 && phase.size()<5){ int b = first ? pickBFirst(m) : pickB(m); int k = first ? ((b*(b+1)/2 -1) + 4-1)/4 : ((b*b -1) + 4-1)/4; phase.emplace_back(m,b,k,pos, first); m = (m + b - 1)/b + k - 1; pos += k; first = false; } reverse(phase.begin(), phase.end()); if(pos==Nglob-3 && phase.size()==5 && m<=4) break; } } vi sliceCandidates(const vi &C,int bu,int b){ int s = bu*b, e = min((int)C.size(), s+b); return vi(C.begin()+s, C.begin()+e); } vi candP, candQ; pair<int,int> delayed; int previous; vector<vi> G; int bfs_far(int src,int N){ vi dist(N,-1); queue<int>q; dist[src]=0; q.push(src); while(!q.empty()){ int u=q.front();q.pop(); for(int v:G[u]) if(dist[v]<0){ dist[v]=dist[u]+1; q.push(v); } } return max_element(dist.begin(),dist.end())-dist.begin(); } pair<int,int> getDiameter(int N){ int u=bfs_far(0,N); int v=bfs_far(u,N); return {u,v}; } bool same(ii a,ii b){ if(a.first>a.second) swap(a.first, a.second); if(b.first>b.second) swap(b.first, b.second); return a==b; } int P1,P2,Q1,Q2,Q3; int R1,R2,R3; int lastU,lastV; int send_message(int N, int i, int p) { if(N<=9){ if(i==1){ G.assign(N,{}); lastU=0; lastV=1; } G[i].push_back(p); G[p].push_back(i); if(i>=2){ auto [u,v] = getDiameter(N); if(u>v) swap(u,v); int mes; if (u==lastU && v==lastV) mes = 0; else if (v!= lastV && u==lastU) mes = 1; else mes = 2; lastU=u; lastV=v; return mes; } return 0; } if(i==1){ Nglob = N; G.assign(N, {}); calculateCandidates(phases); candP.clear(); candQ.clear(); candP.push_back(0); candQ.push_back(0); delayed = {-1,-1}; } G[i].push_back(p); G[p].push_back(i); if(i<N-3){ candP.push_back(i); candQ.push_back(i); } if(i == phases.back().start){ auto [u,v] = getDiameter(N); Phase actual = phases.back(); if(find(candP.begin(), candP.end(), u) == candP.end() || find(candQ.begin(), candQ.end(), v)==candQ.end()) swap(u,v); int idU = find(candP.begin(), candP.end(), u) - candP.begin(); int idV = find(candQ.begin(), candQ.end(), v) - candQ.begin(); int blockSize=ceil((double)actual.m/(double)actual.b); int blockU = idU/blockSize, blockV = idV/blockSize; candP = sliceCandidates(candP, blockU, blockSize); candQ = sliceCandidates(candQ, blockV, blockSize); if(actual.tri){ if(u>v) { swap(u,v); swap(candP,candQ); swap(blockU, blockV); } int B = actual.b; int index = 0; for (int bu = 0; bu < blockU; ++bu) index += (B - bu); index += (blockV-blockU); if (index >= 0) { int raw = index-1; int card = i + raw / 4; int num = (raw % 4) + 1; delayed = { card, num }; } } else{ int cells = blockU * actual.b + blockV; if(cells!=0){ int card = i + (cells-1) / 4; int num = ((cells-1) % 4)+1; delayed = {card, num}; } } phases.pop_back(); } if(i == delayed.first){ return delayed.second; } if(i==N-3){ while(candP.size()<4) candP.push_back(0); while(candQ.size()<4) candQ.push_back(0); int p1=candP[0], p2=candP[1], p3=candP[2], p4=candP[3]; int q1=candQ[0], q2=candQ[1], q3=candQ[2], q4=candQ[3]; vector<ii> cand = { ii(p1,q1), ii(p1,q2), ii(p1,q3), ii(p2, q1), ii(p2,q2), ii(p1,q4), ii(p1,i), ii(p2,q3), ii(p2, q4), ii(p2,i), ii(p3,q1), ii(p3,q2), ii(p4,q1), ii(p4, q2), ii(i,q1), ii(p3,q3), ii(p3,q4), ii(p3,i), ii(p4, q4), ii(p4,i), ii(p4,q3), ii(i,q2), ii(i,q3), ii(i, q4) }; auto [u,v] = getDiameter(Nglob); if(find(cand.begin(),cand.end(), ii(u,v))==cand.end()) swap(u,v); int id = find(cand.begin(), cand.end(), ii(u,v)) - cand.begin(); int label = id/5; previous = label; return previous; } if(i==N-2){ int a1=candP[0], a2=candP[1], a3=candP[2], a4=candP[3]; int b1=candQ[0], b2=candQ[1], b3=candQ[2], b4=candQ[3]; if(previous == 0){ P1=a1; P2=a2; Q1=b1; Q2=b2; Q3=b3; } if(previous == 1){ P1=a2; P2=a1; Q1=i-1; Q2=b4; Q3=b3; } if(previous == 2){ P1=b1; P2=b2; Q1=a3; Q2=a4; Q3=i-1; } if(previous == 3){ P1=a3; P2=a4; Q1=i-1; Q2=b4; Q3=b3; } if(previous == 4){ P1=i-1; P2=a4; Q1=b2; Q2=b3; Q3=b4; } vector<ii> cand = { ii(P1, Q1), ii(P2, Q1), ii(P1, Q2), ii(P2,Q2), ii(P1, Q3), ii(i, Q3), ii(i, Q1), ii(i, Q2), ii(P1,i), ii(P2,i) }; auto [u,v] = getDiameter(Nglob); if(find(cand.begin(),cand.end(), ii(u,v))==cand.end()) swap(u,v); int id = find(cand.begin(), cand.end(), ii(u,v)) - cand.begin(); int label = id/2; previous = label; return previous; } if(i==N-1){ int r1=0,r2=0,r3=0; if(previous == 0){ r3=Q1; r2=P1; r1=P2; } if(previous == 1) { r3=Q2; r2=P1; r1=P2; } if(previous == 2) { r3=Q3; r2=P1; r1=N-2; } if(previous == 3){ r3=N-2; r2=Q1; r1=Q2; } if(previous == 4){ r3=N-2; r2=P1; r1=P2; } auto [u,v] = getDiameter(Nglob); if(same(ii(u,v), ii(r1,r3))) return 0; if(same(ii(u,v), ii(r2,r3))) return 1; if(same(ii(u,v), ii(r1,i))) return 2; if(same(ii(u,v), ii(r2,i))) return 3; if(same(ii(u,v), ii(r3,i))) return 4; } return 0; } pair<int,int> longest_path(vector<int> S) { int N = S.size(); Nglob=S.size(); if(N<=9){ int u=0,v=1; for(int i=1;i<N;i++){ int p=S[i]; if(p==1) v=i; if(p==2){ u=v; v=i; } } return {u,v}; } candP.clear(); candQ.clear(); calculateCandidates(phases); int pos=0; while(!phases.empty()){ Phase phase = phases.back(); while(pos!=phase.start+1){ candP.push_back(pos); candQ.push_back(pos); pos++; } int c=0, message=-1; for(int i=pos-1;i<pos+phase.k-1;i++){ if(S[i]!=0){ message=S[i]; break; } c++; } int cells = (message==-1)? 0 : (c*4+message); int blockU=0, blockV=0; int blockSize=ceil((double)phase.m/(double)phase.b); if(phase.tri){ int B = phase.b; cells++; for (int u = 0; u < B; ++u) { int row = B - u; if (cells <= row) { blockU = u; blockV = u + (cells - 1); break; } cells -= row; } } else{ blockU = cells/phase.b; blockV = cells%phase.b; } candP = sliceCandidates(candP, blockU, blockSize); candQ = sliceCandidates(candQ, blockV, blockSize); for(int i=pos;i<pos+phase.k-1;i++){ candP.push_back(i); candQ.push_back(i); } pos=pos+phase.k-1; phases.pop_back(); } while(candP.size()<4) candP.push_back(0); while(candQ.size()<4) candQ.push_back(0); int a1=candP[0], a2=candP[1], a3=candP[2], a4=candP[3]; int b1=candQ[0], b2=candQ[1], b3=candQ[2], b4=candQ[3]; if(S[N-3] == 0){ P1=a1; P2=a2; Q1=b1; Q2=b2; Q3=b3; } if(S[N-3] == 1){ P1=a2; P2=a1; Q1=N-3; Q2=b4; Q3=b3; } if(S[N-3] == 2){ P1=b1; P2=b2; Q1=a3; Q2=a4; Q3=N-3; } if(S[N-3] == 3){ P1=a3; P2=a4; Q1=N-3; Q2=b4; Q3=b3; } if(S[N-3] == 4){ P1=N-3; P2=a4; Q1=b2; Q2=b3; Q3=b4; } int r1 = 0, r2 = 0, r3 = 0; if(S[N-2] == 0){ r3=Q1; r2=P1; r1=P2; } if(S[N-2] == 1) { r3=Q2; r2=P1; r1=P2; } if(S[N-2] == 2) { r3=Q3; r2=P1; r1=N-2; } if(S[N-2] == 3){ r3=N-2; r2=Q1; r1=Q2; } if(S[N-2] == 4){ r3=N-2; r2=P1; r1=P2; } if(S[N-1] == 0) return {r1,r3}; if(S[N-1] == 1) return {r2,r3}; if(S[N-1] == 2) return {r1,N-1}; if(S[N-1] == 3) return {r2,N-1}; if(S[N-1] == 4) return {r3,N-1}; return {0, 0}; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...