Submission #1302189

#TimeUsernameProblemLanguageResultExecution timeMemory
1302189regulardude6Hieroglyphs (IOI24_hieroglyphs)C++20
100 / 100
110 ms45088 KiB
#include "hieroglyphs.h" #include <bits/stdc++.h> using namespace std; static const int SIG = 200001; static const int INF = 1e9; struct BITMax { int n; vector<int> bit; BITMax(int n=0){ init(n); } void init(int n_){ n = n_; bit.assign(n+1, -1); } void upd(int pos, int val){ int i = n - pos; for(; i <= n; i += i & -i) bit[i] = max(bit[i], val); } int query_suffix_gt(int th){ if(th >= n-1) return -1; int lim = n - (th+1); int res = -1; for(int i = lim; i > 0; i -= i & -i) res = max(res, bit[i]); return res; } }; static inline int next_pos(const vector<int>& v, int after){ auto it = upper_bound(v.begin(), v.end(), after); if(it == v.end()) return INF; return *it; } static vector<int> compute_VL(const vector<int>& S, const vector<vector<int>>& posS, const vector<int>& T){ int n = (int)S.size(); int m = (int)T.size(); vector<int> prev(m, -1); static vector<int> last(SIG, -1); for(int i=0;i<SIG;i++) last[i] = -1; for(int i=0;i<m;i++){ int c = T[i]; prev[i] = last[c]; last[c] = i; } int SZ = 1; while(SZ < m) SZ <<= 1; vector<int> seg(2*SZ, INF); auto seg_set = [&](int idx, int val){ int p = idx + SZ; seg[p] = val; for(p >>= 1; p; p >>= 1) seg[p] = min(seg[p<<1], seg[p<<1|1]); }; auto seg_min = [&](int l, int r){ if(l > r) return INF; l += SZ; r += SZ; int res = INF; while(l <= r){ if(l & 1) res = min(res, seg[l++]); if(!(r & 1)) res = min(res, seg[r--]); l >>= 1; r >>= 1; } return res; }; vector<int> dp(m, INF); for(int i=0;i<m;i++){ int c = T[i]; int bestPrev; if(prev[i] == -1){ bestPrev = min(-1, (i==0 ? INF : seg_min(0, i-1))); } else { bestPrev = seg_min(prev[i], i-1); } if(bestPrev >= INF) dp[i] = INF; else dp[i] = next_pos(posS[c], bestPrev); seg_set(i, dp[i]); } return dp; } static vector<int> compute_VR(const vector<int>& S, const vector<vector<int>>& posSr, const vector<int>& T){ int n = (int)S.size(); int m = (int)T.size(); vector<int> Tr = T; reverse(Tr.begin(), Tr.end()); vector<int> VLr = compute_VL(vector<int>(), posSr, Tr); vector<int> VR(m, -1); for(int i=0;i<m;i++){ int x = VLr[m-1-i]; if(x >= INF) VR[i] = -1; else VR[i] = n-1-x; } return VR; } static bool embed_left(const vector<int>& P, const vector<int>& S, vector<int>& out){ out.resize(P.size()); int p = 0; for(int i=0;i<(int)P.size();i++){ int x = P[i]; while(p < (int)S.size() && S[p] != x) p++; if(p == (int)S.size()) return false; out[i] = p++; } return true; } static bool embed_right(const vector<int>& P, const vector<int>& S, vector<int>& out){ out.resize(P.size()); int p = (int)S.size()-1; for(int i=(int)P.size()-1;i>=0;i--){ int x = P[i]; while(p >= 0 && S[p] != x) p--; if(p < 0) return false; out[i] = p--; } return true; } static inline bool block_common( int x, int kx, int y, int ly, const vector<vector<int>>& posA, const vector<vector<int>>& posB ){ const auto &Ax = posA[x], &Ay = posA[y]; const auto &Bx = posB[x], &By = posB[y]; if((int)Ax.size() < kx || (int)Ay.size() < ly) return false; if((int)Bx.size() < kx || (int)By.size() < ly) return false; int ax = Ax[kx-1]; int ay = Ay[(int)Ay.size() - ly]; int bx = Bx[kx-1]; int by = By[(int)By.size() - ly]; return ax < ay && bx < by; } vector<int> ucs(vector<int> A, vector<int> B) { int N = (int)A.size(), M = (int)B.size(); vector<int> occA(SIG,0), occB(SIG,0); vector<vector<int>> posA(SIG), posB(SIG); vector<char> inA(SIG,0), inB(SIG,0); for(int i=0;i<N;i++){ int x = A[i]; if(0<=x && x<SIG){ occA[x]++; posA[x].push_back(i); inA[x]=1; } } for(int i=0;i<M;i++){ int x = B[i]; if(0<=x && x<SIG){ occB[x]++; posB[x].push_back(i); inB[x]=1; } } vector<char> common(SIG,0), aweak(SIG,0); for(int x=0;x<SIG;x++){ if(inA[x] && inB[x]){ common[x]=1; aweak[x] = (occA[x] <= occB[x]); } } vector<int> WA, WB; WA.reserve(N); WB.reserve(M); for(int x: A) if(common[x] && aweak[x]) WA.push_back(x); for(int x: B) if(common[x] && !aweak[x]) WB.push_back(x); vector<int> usedA(SIG,0), usedB(SIG,0); vector<int> C; C.reserve(WA.size() + WB.size()); int i=0, j=0; while(i < (int)WA.size() && j < (int)WB.size()){ int x = WA[i], y = WB[j]; int k1 = usedA[x] + 1; int l1 = occB[y] - usedB[y]; int k2 = usedB[y] + 1; int l2 = occA[x] - usedA[x]; bool ok1 = block_common(x, k1, y, l1, posA, posB); bool ok2 = block_common(y, k2, x, l2, posA, posB); if(ok1 ^ ok2){ if(ok1){ C.push_back(x); usedA[x]++; i++; } else { C.push_back(y); usedB[y]++; j++; } } else { return vector<int>{-1}; } } while(i < (int)WA.size()) C.push_back(WA[i++]); while(j < (int)WB.size()) C.push_back(WB[j++]); vector<int> LA, LB, RA, RB; if(!embed_left(C, A, LA)) return vector<int>{-1}; if(!embed_left(C, B, LB)) return vector<int>{-1}; if(!embed_right(C, A, RA)) return vector<int>{-1}; if(!embed_right(C, B, RB)) return vector<int>{-1}; int L = (int)C.size(); vector<int> wL(L), wR(L); for(int t=0;t<L;t++){ int x = C[t]; if(aweak[x]){ wL[t] = LA[t]; wR[t] = RA[t]; } else { wL[t] = LB[t]; wR[t] = RB[t]; } } vector<vector<int>> posAr(SIG), posBr(SIG); for(int x=0;x<SIG;x++){ if(!posA[x].empty()){ posAr[x].reserve(posA[x].size()); for(int p: posA[x]) posAr[x].push_back(N-1-p); sort(posAr[x].begin(), posAr[x].end()); } if(!posB[x].empty()){ posBr[x].reserve(posB[x].size()); for(int p: posB[x]) posBr[x].push_back(M-1-p); sort(posBr[x].begin(), posBr[x].end()); } } vector<int> VL_A = compute_VL(A, posA, C); vector<int> VL_B = compute_VL(B, posB, C); vector<int> Cr = C; reverse(Cr.begin(), Cr.end()); vector<int> VL_Ar = compute_VL(vector<int>(), posAr, Cr); vector<int> VL_Br = compute_VL(vector<int>(), posBr, Cr); vector<int> VR_A(L, -1), VR_B(L, -1); for(int t=0;t<L;t++){ int a = VL_Ar[L-1-t]; int b = VL_Br[L-1-t]; VR_A[t] = (a >= INF ? -1 : N-1-a); VR_B[t] = (b >= INF ? -1 : M-1-b); } BITMax bitA(N), bitB(M); for(int t=0;t<L;t++){ int x = C[t]; if(!aweak[x]){ int th = VL_A[t]; if(th < INF){ int best = bitA.query_suffix_gt(th); if(best > wL[t]) return vector<int>{-1}; } } if(aweak[x] && VR_B[t] != -1){ bitA.upd(wR[t], VR_B[t]); } } for(int t=0;t<L;t++){ int x = C[t]; if(aweak[x]){ int th = VL_B[t]; if(th < INF){ int best = bitB.query_suffix_gt(th); if(best > wL[t]) return vector<int>{-1}; } } if(!aweak[x] && VR_A[t] != -1){ bitB.upd(wR[t], VR_A[t]); } } return C; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...