Submission #1302185

#TimeUsernameProblemLanguageResultExecution timeMemory
1302185regulardude6Hieroglyphs (IOI24_hieroglyphs)C++20
3 / 100
69 ms29352 KiB
#include "hieroglyphs.h" #include <bits/stdc++.h> using namespace std; static const int V = 200002; static const int INF = 1000000007; struct SegMin { int n; vector<int> st; void init(int N){ n = N; st.assign(4*n+4, INF); } void upd(int p, int l, int r, int idx, int val){ if(l==r){ st[p] = min(st[p], val); return; } int m=(l+r)>>1; if(idx<=m) upd(p<<1,l,m,idx,val); else upd(p<<1|1,m+1,r,idx,val); st[p]=min(st[p<<1],st[p<<1|1]); } int ql(int p,int l,int r,int q){ if(q>=r) return st[p]; int m=(l+r)>>1; if(q<=m) return min(ql(p<<1,l,m,q), st[p<<1|1]); return ql(p<<1|1,m+1,r,q); } int qr(int p,int l,int r,int q){ if(q<=l) return st[p]; int m=(l+r)>>1; if(q>m) return min(st[p<<1], qr(p<<1|1,m+1,r,q)); return qr(p<<1,l,m,q); } }; static SegMin seg; static inline bool is_sq(const vector<int>& Ax, const vector<int>& Ay, const vector<int>& Bx, const vector<int>& By, int k, int l){ if((int)Ax.size() < k || (int)Ay.size() < l) return false; if((int)Bx.size() < k || (int)By.size() < l) return false; int ax = Ax[k-1], ay = Ay[(int)Ay.size()-l]; int bx = Bx[k-1], by = By[(int)By.size()-l]; return ax < ay && bx < by; } vector<int> ucs(vector<int> A, vector<int> B) { int N = (int)A.size(), M = (int)B.size(); vector<vector<int>> posA(V), posB(V); vector<int> ca(V,0), cb(V,0); for(int i=0;i<N;i++){ int x=A[i]; if(0<=x && x<V){ ca[x]++; posA[x].push_back(i); } } for(int i=0;i<M;i++){ int x=B[i]; if(0<=x && x<V){ cb[x]++; posB[x].push_back(i); } } vector<char> common(V,0), weakA(V,0); for(int x=0;x<V;x++){ if(ca[x] && cb[x]){ common[x]=1; weakA[x] = (ca[x] <= cb[x]); } } vector<int> C, D; C.reserve(N); D.reserve(M); for(int x: A) if(common[x] && weakA[x]) C.push_back(x); for(int x: B) if(common[x] && !weakA[x]) D.push_back(x); vector<int> used(V,0); vector<int> E; E.reserve(C.size() + D.size()); int i=0,j=0; while(i < (int)C.size() || j < (int)D.size()){ if(!E.empty()) used[E.back()]++; if(i==(int)C.size()){ E.push_back(D[j++]); continue; } if(j==(int)D.size()){ E.push_back(C[i++]); continue; } int x = C[i], y = D[j]; if(ca[x]==cb[x] || ca[y]==cb[y]){ if(x==y){ E.push_back(x); i++; j++; continue; } if(ca[x]!=cb[x]){ E.push_back(x); i++; continue; } if(ca[y]!=cb[y]){ E.push_back(y); j++; continue; } return vector<int>{-1}; } int kx = used[x] + 1; int ly = cb[y] - used[y]; int ky = used[y] + 1; int lx = ca[x] - used[x]; bool X = is_sq(posA[x], posA[y], posB[x], posB[y], kx, ly); bool Y = is_sq(posA[y], posA[x], posB[y], posB[x], ky, lx); if(X && Y) return vector<int>{-1}; if(Y){ E.push_back(y); j++; } else if(X){ E.push_back(x); i++; } else return vector<int>{-1}; } int L = (int)E.size(); vector<int> fA1(L), fA2(L), fB1(L), fB2(L); { int p=0; for(int t=0;t<L;t++){ while(p<N && A[p]!=E[t]) p++; if(p==N) return vector<int>{-1}; fA1[t]=p++; } p=N-1; for(int t=L-1;t>=0;t--){ while(p>=0 && A[p]!=E[t]) p--; if(p<0) return vector<int>{-1}; fA2[t]=p--; } } { int p=0; for(int t=0;t<L;t++){ while(p<M && B[p]!=E[t]) p++; if(p==M) return vector<int>{-1}; fB1[t]=p++; } p=M-1; for(int t=L-1;t>=0;t--){ while(p>=0 && B[p]!=E[t]) p--; if(p<0) return vector<int>{-1}; fB2[t]=p--; } } vector<int> last(V,-1), prv(L,-1); for(int t=0;t<L;t++){ int x=E[t]; prv[t]=last[x]; last[x]=t; } auto build_side = [&](const vector<int>& S, int n, const vector<vector<int>>& pos, bool rev)->vector<int>{ int m=(int)S.size(); int SZ=1; while(SZ<m) SZ<<=1; vector<int> segv(2*SZ, INF); auto seg_set = [&](int idx,int val){ int p=idx+SZ; segv[p]=val; for(p>>=1;p;p>>=1) segv[p]=min(segv[p<<1],segv[p<<1|1]); }; auto seg_q = [&](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, segv[l++]); if(!(r&1)) res=min(res, segv[r--]); l>>=1; r>>=1; } return res; }; vector<int> dp(m, INF); for(int t=0;t<m;t++){ int x=S[t]; int mp = (prv[t]==-1)? -1 : seg_q(prv[t], t-1); if(mp>=INF){ dp[t]=INF; }else{ const auto &vec=pos[x]; if(!rev){ auto it = upper_bound(vec.begin(), vec.end(), mp); dp[t] = (it==vec.end()? INF : *it); }else{ int bound = (n-1) - mp; auto it = lower_bound(vec.begin(), vec.end(), bound); if(it==vec.begin()) dp[t]=INF; else { --it; dp[t]=(n-1)-*it; } } } seg_set(t, dp[t]); } return dp; }; vector<int> VL_A = build_side(E, N, posA, false); vector<int> VL_B = build_side(E, M, posB, false); vector<int> Er = E; reverse(Er.begin(), Er.end()); vector<int> VLAr = build_side(Er, N, posA, true); vector<int> VLBr = build_side(Er, M, posB, true); vector<int> VR_A(L,-1), VR_B(L,-1); for(int t=0;t<L;t++){ int a = VLAr[L-1-t]; int b = VLBr[L-1-t]; VR_A[t] = (a>=INF? -1 : (N-1)-a); VR_B[t] = (b>=INF? -1 : (M-1)-b); } vector<int> wL(L), wR(L); for(int t=0;t<L;t++){ int x=E[t]; if(weakA[x]){ wL[t]=fA1[t]; wR[t]=fA2[t]; } else { wL[t]=fB1[t]; wR[t]=fB2[t]; } } seg.init(N+2); for(int t=0;t<L;t++){ int x=E[t]; if(!weakA[x]){ int q = seg.qr(1,1,seg.n, VL_A[t]+2); if(q < wL[t]) return vector<int>{-1}; } if(weakA[x] && VR_B[t]!=-1){ seg.upd(1,1,seg.n, wR[t]+1, (seg.n-1)-VR_B[t]); } } seg.init(M+2); for(int t=0;t<L;t++){ int x=E[t]; if(weakA[x]){ int q = seg.qr(1,1,seg.n, VL_B[t]+2); if(q < wL[t]) return vector<int>{-1}; } if(!weakA[x] && VR_A[t]!=-1){ seg.upd(1,1,seg.n, wR[t]+1, (seg.n-1)-VR_A[t]); } } return E; }
#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...