Thoroughly pit teammate = =
A. Equivalent Prefixes
[Idea] on the examination room
Front to back sweep, the current location of a $ I $, added after determining whether the equivalent, is determined corresponding to $ j = max \ {j \ text {|} a [j] <a [i], j <i \} $, $ k = max \ {k \ text {|} b [k] <b [i], k <i \} $ are equal
This can be binary + segment sloth mark resolved:
Each time interval assigned to a $ a [i], b [i] $ interval corresponding to the segment tree $ [j + 1, i] $ $ I $ are assigned (if assigned, is tacitly $ j = k $ ), the subscript represents the minimum of this interval is the number of $ I $
Then for the new $ i $, you can find half of $ j $, $ k $
Overall complexity $ O (n (logn) ^ 2) $
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=100005; int n; int a[N],b[N]; struct SegTree { int sz; int t[N<<2],tag[N<<2]; void Init(int x) { sz=x; for(int i=1;i<(sz<<1);i++) t[i]=tag[i]=0; } inline void Push(int k) { if(!tag[k]) return; t[k]=tag[k]; tag[k]=0; if(k>=sz) return; tag[k<<1]=tag[k<<1|1]=t[k]; } inline void Add(int k,int l,int r,int a,int b,int x) { Push(k); if(a>r || b<l) return; if(a>=l && b<=r) { tag[k]=x; Push(k); return; } int mid=(a+b)>>1; Add(k<<1,l,r,a,mid,x); Add(k<<1|1,l,r,mid+1,b,x); } inline int Query(int k,int p,int a,int b) { Push(k); if(a==b) return t[k]; int mid=(a+b)>>1; if(p<=mid) return Query(k<<1,p,a,mid); else return Query(k<<1|1,p,mid+1,b); } }ta,tb; int main() { while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%d",&b[i]); int sz=1; while(sz<n) sz<<=1; ta.Init(sz),tb.Init(sz); int ans=1; ta.Add(1,1,1,1,sz,1); tb.Add(1,1,1,1,sz,1); for(int i=2;i<=n;i++) { int pa,pb; int left=1,right=i-1,mid; while(left<right) { mid=(left+right)>>1; if(a[ta.Query(1,mid,1,sz)]<a[i]) left=mid+1; else right=mid; } if(a[left]>a[i]) left--; pa=left; left=1,right=i-1; while(left<right) { mid=(left+right)>>1; if(b[tb.Query(1,mid,1,sz)]<b[i]) left=mid+1; else right=mid; } if(b[left]>b[i]) left--; pb=left; if(pa!=pb) break; ans=i; ta.Add(1,pa+1,i,1,sz,i); tb.Add(1,pb+1,i,1,sz,i); } printf("%d\n",ans); } return 0; }
[Normal practice]