Two arrays u and v each with m distinct elements are called equivalent if and only if RMQ(u,l,r)=RMQ(v,l,r)RMQ(u,l,r)=RMQ(v,l,r) for all 1≤l≤r≤m1≤l≤r≤m
where RMQ(w,l,r)RMQ(w,l,r) denotes the index of the minimum element among wl,wl+1,…,wrwl,wl+1,…,wr.
Since the array contains distinct elements, the definition of minimum is unambiguous.
 
Bobo has two arrays a and b each with n distinct elements. Find the maximum number p≤np≤n where {a1,a2,…,ap}{a1,a2,…,ap} and {b1,b2,…,bp}{b1,b2,…,bp} are equivalent.
 
 where RMQ(w,l,r)RMQ(w,l,r) denotes the index of the minimum element among wl,wl+1,…,wrwl,wl+1,…,wr.
Since the array contains distinct elements, the definition of minimum is unambiguous.
Bobo has two arrays a and b each with n distinct elements. Find the maximum number p≤np≤n where {a1,a2,…,ap}{a1,a2,…,ap} and {b1,b2,…,bp}{b1,b2,…,bp} are equivalent.
输入描述:
The input consists of several test cases and is terminated by end-of-file. The first line of each test case contains an integer n. The second line contains n integers a1,a2,…,ana1,a2,…,an. The third line contains n integers b1,b2,…,bnb1,b2,…,bn. * 1≤n≤1051≤n≤105 * 1≤ai,bi≤n1≤ai,bi≤n * {a1,a2,…,an}{a1,a2,…,an} are distinct. * {b1,b2,…,bn}{b1,b2,…,bn} are distinct. * The sum of n does not exceed 5×1055×105.
输出描述:
For each test case, print an integer which denotes the result.
  题意大概就是两个数组,找最大的p,使对于1到p的所有子区间都保证最小值的下标相同; 
   这时我们就可以发现,如果a[i]<a[i+1]&&b[i]<b[i+1],则a[i+1]和b[i+1]对之前所有子区间都不构成影响,因为总有min(a[1],a[i])比a[i+1]小; 
   那么我们可以线性的考虑,对于a[i]<a[i+1]&&b[i]<b[i+1]这种情况直接跳过,其他的情况则往前寻找第一个比a[i](b[i])小的数,如果下标相等则符合;如果下标不等则说明了不能取,证明如下:  
   设往前寻找第一个比a[i]小的数的下标为k1,同理b为k2,如果k1!=k2,则在(min(k1,k2),i)这个子区间上不成立,反正成立(都推到i了,则前面的肯定经过了一样的推理证明成立,可知所有子区间均成立) 
   找前面的第一个比自身小的数可以用单调栈的思想来标记(由于某人不会,我粗略说一下这题的用法),每次找到当前项符合的值,记录下标,到下次往前找的时候可以直接跳到这一项的符合值; 
   比如设当前为第k项,找到了第m项是符合的,则下次第i项(i>k)往前搜索搜到k时可直接跳到第m项。 
   代码如下: 
 #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3fffffff
#define maxn 100005
int n,m,k,t;
int a[maxn],b[maxn],num1[maxn],num2[maxn];
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]);
        a[0]=b[0]=0;
        num1[1]=num2[1]=0;
        for(int i=2;i<=n;i++){
            int k1=i-1,k2=i-1;
            while(a[i]<a[k1])
                k1=num1[k1];
            num1[i]=k1;
            while(b[i]<b[k2])
                k2=num2[k2];
            num2[i]=k2;
            if(num1[i]!=num2[i]){
                printf("%d\n",i-1);
                break;
            }
            if(i==n)
                printf("%d\n",n);
        }
    }
} 
 京公网安备 11010502036488号
京公网安备 11010502036488号