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

传送门

题意:

先输入一个n,代表两个数组里面都有n个数,然后让你从中找到一个p<=n,使其满足(1<=l<=r<=p<=n)可以让在(l,r)这个区间内在两个数组中的的最小值的下标一样

 

题解:

参考博客:

我一直认为区间起点l一直是1,突然发现他还可以变T_T

p为1肯定对着咧

当p大于1的时候,我们只需要判断两个数组中的每一个位置在左边遇见的第一个最小值的位置是相同的,一直找到不相同的位置,那个位置就是最大的p,那么这样的话就可以通过小区间的最小值位置相同依次证明大区间的最小值位置相同

假设我们证明(1,4)区间最小值位置

前提条件(3,4)最小值位置在3,(1,3)最小值位置相同

解:

那么从(3,4)这个区间找到最小值位置是3,又因为两个区间在(1,3)最小值位置相同,所以整个(1,4)区间最小值位置都相同

 

代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 #include<queue>
 5 #include<algorithm>
 6 #include<vector>
 7 #include<stack>
 8 using namespace std;
 9 const int maxn=1e5+10;
10 int a[maxn],b[maxn],la[maxn],lb[maxn];
11 stack<int>sa,sb;
12 int main()
13 {
14     int n;
15     while(~scanf("%d",&n))
16     {
17         for(int i=1; i<=n; ++i)
18         {
19             scanf("%d",&a[i]);
20         }
21         for(int i=1; i<=n; ++i)
22         {
23             scanf("%d",&b[i]);
24         }
25         while(!sa.empty()) sa.pop();
26         for(int i=1;i<=n;++i)
27         {
28             while(!sa.empty() && a[i]<a[sa.top()]) sa.pop();
29             if(sa.empty()) la[i]=0;
30             else la[i]=sa.top();   //找的是左边第一个小于它的数
31             sa.push(i); //如果靠着他的左边那个数不小于它,那大于左边那个数的数也不可取
32         }
33         while(!sb.empty()) sb.pop();
34         for(int i=1;i<=n;++i)
35         {
36             while(!sb.empty() && b[i]<b[sb.top()]) sb.pop();
37             if(sb.empty()) lb[i]=0;
38             else lb[i]=sb.top();
39             sb.push(i);
40         }
41         int ans=1;
42         for(int i=2;i<=n;++i)
43         {
44             if(la[i]==lb[i]) ans=i;
45             else break;
46         }
47         printf("%d\n",ans);
48     }
49     return 0;
50 }
View Code

 

posted @ 2019-08-01 10:19  kongbursi  阅读(160)  评论(0编辑  收藏  举报