2019牛客暑期多校训练营(第一场)

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 }
View Code

J

猜你喜欢

转载自www.cnblogs.com/Accpted/p/11209471.html