A.Equivalent+Prefixes
思路:
二分答案,然后运用单调栈求出右边第一个比它小的数,若对于每一个二分答案左边的每一个数右边第一个比它小的数位置必须相同。
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int N=200000; 6 int s[N],tot,a[N],b[N],f1[N],c[N],d[N],f2[N],n; 7 bool check(int x) 8 { 9 for (int i=1; i<=x; i++) 10 { 11 if (f1[i]!=f2[i]) 12 { 13 return 0; 14 } 15 } 16 return 1; 17 } 18 19 void work(int a[],int f[],int d[],int n) 20 { 21 tot=0; 22 for (int i=n; i>=1; i--) 23 { 24 while (tot>0&&s[tot]>a[i]) 25 { 26 tot--; 27 } 28 s[++tot]=a[i]; 29 if (tot>1) 30 { 31 f[i]=d[s[tot-1]]; 32 } 33 else 34 { 35 f[i]=-1; 36 } 37 } 38 } 39 40 int main() 41 { 42 while(~scanf("%d",&n)) 43 { 44 for (int i=1; i<=n; i++) 45 { 46 scanf("%d",&a[i]); 47 c[a[i]]=i; 48 } 49 for (int i=1; i<=n; i++) 50 { 51 scanf("%d",&b[i]); 52 d[b[i]]=i; 53 } 54 int l=1,r=n,ans=1; 55 while (l<=r) 56 { 57 int mid=(l+r)>>1; 58 work(a,f1,c,mid); 59 work(b,f2,d,mid); 60 if (check(mid)) 61 { 62 l=mid+1; 63 ans=mid; 64 } 65 else 66 { 67 r=mid-1; 68 } 69 } 70 printf("%d\n",ans); 71 } 72 }
J