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

本文介绍了一种解决特定RMQ问题的方法,通过对比两个数组在不同区间内的最小值位置来找出最长的等价子数组。文章详细阐述了解决方案的思路,并提供了实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述
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)RMQ(u,l,r)=RMQ(v,l,r)
for all 1≤l≤r≤m1≤l≤r≤m1lrm
where RMQ(w,l,r)RMQ(w,l,r)RMQ(w,l,r) denotes the index of the minimum element among wwwl,wwwl+1,…,wwwr
Since the array contains distinct elements, the definition of minimum is unambiguous.
Bobo has two arrays a and b each with nnn distinct elements. Find the maximum number p≤np≤npn where a1,a2,…,ap{a_1,a_2,…,a_p}a1,a2,,ap and b1,b2,…,bp{b_1,b_2,…,b_p}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 nnn.
The second line contains nnn integers a1a_1a1,a2a_2a2,…,ana_nan

The third line contains nnn integers b1b_1b1,b2b_2b2,…,bnb_nbn.

  • 1≤n≤101≤n≤101n105
  • 1≤1≤1aia_iai,bi≤nb_i≤nbin
  • a1,a2,…,an{a_1,a_2,…,a_n}a1,a2,,an are distinct.
  • b1,b2,…,bn{b_1,b_2,…,b_n}b1,b2,,bn are distinct.
  • The sum of nnn does not exceed 5×105×105×105

输出描述:
For each test case, print an integer which denotes the result…
样例输入

2
1 2
2 1
3
2 1 3
3 1 2
5
3 1 5 2 4
5 2 4 3 1

样例输出

1
3
4

题意
题目包含多组输入数据,每组数据相互独立。
题目定义了RMQ(v,l,r)RMQ(v,l,r)RMQ(v,l,r)的值是对于数组v,在[l,r][l,r][l,r]内值最小的元素的下标。
而对于两个长度均为mmm的数组u、v,若对于任意1≤l≤r≤m1≤l≤r≤m1lrm均有RMQ(u,l,r)=RMQ(v,l,r)RMQ(u,l,r)=RMQ(v,l,r)RMQ(u,l,r)=RMQ(v,l,r)则认为这两个数组是相等的。现在给出nnn及两个长度为nnn的数组,求最大的ppp对于任意1≤l≤r≤p1≤l≤r≤p1lrp满足RMQ(u,l,r)=RMQ(v,l,r)RMQ(u,l,r)=RMQ(v,l,r)RMQ(u,l,r)=RMQ(v,l,r),并输出这个ppp值。

思路
对于p=1p=1p=1的情况显然满足题意,故ppp的最小值为1。
考虑p>1p>1p>1的情况,假设p−1p-1p1是满足题意的,那么我们只需要考虑对于任意1≤l≤p1≤l≤p1lp是否均满足RMQ(u,l,p)=RMQ(v,l,p)RMQ(u,l,p)=RMQ(v,l,p)RMQ(u,l,p)=RMQ(v,l,p)即可
minv[1]minv[1]minv[1]v[1]v[1]v[1] ~ v[p−1]v[p-1]v[p1]的最小值的下标,minu[1]minu[1]minu[1]u[1]u[1]u[1] ~ u[p−1]u[p-1]u[p1]的最小值的下标,
minv[i]minv[i]minv[i]v[minv[i−1]+1] v[p−1]v[minv[i-1]+1] ~ v[p-1]v[minv[i1]+1] v[p1]的最小值的下标,minu[i]minu[i]minu[i]u[minu[i−1]+1] u[p−1]u[minu[i-1]+1] ~ u[p-1]u[minu[i1]+1] u[p1]的最小值的下标(2≤i≤h2≤i≤h2ih)

  • v[p]v[p]v[p]<v[minv[1]]v[minv[1]]v[minv[1]]u[p]u[p]u[p]<u[minu[1]]u[minu[1]]u[minu[1]]
    那么显然对于任意1≤l≤p1≤l≤p1lp均满足RMQ(u,l,p)=RMQ(v,l,p)=pRMQ(u,l,p)=RMQ(v,l,p)=pRMQ(u,l,p)=RMQ(v,l,p)=p,此时可将minu[1]minu[1]minu[1]minv[1]minv[1]minv[1]均刷新为ppp,且将hhh置为1。
  • v[p]v[p]v[p]<v[minv[1]]v[minv[1]]v[minv[1]]u[p]u[p]u[p]>u[minu[1]]u[minu[1]]u[minu[1]]

    v[p]v[p]v[p]>v[minv[1]]v[minv[1]]v[minv[1]]u[p]u[p]u[p]<u[minu[1]]u[minu[1]]u[minu[1]]
    则必有RMQ(u,1,r)!=RMQ(v,1,r)RMQ(u,1,r)!=RMQ(v,1,r)RMQ(u,1,r)=RMQ(v,1,r)(一个值为ppp另一个不为ppp)则ppp不符合题意,答案为p−1p-1p1
  • v[p]v[p]v[p]>v[minv[1]]v[minv[1]]v[minv[1]]u[p]u[p]u[p]>u[minu[1]]u[minu[1]]u[minu[1]]
    那么显然对于任意1≤l≤minu[1]1≤l≤minu[1]1lminu[1]满足RMQ(u,l,p)=RMQ(v,l,p)=minu[1]RMQ(u,l,p)=RMQ(v,l,p)=minu[1]RMQ(u,l,p)=RMQ(v,l,p)=minu[1],我们只需要考虑minu[1]+1≤l≤pminu[1]+1≤l≤pminu[1]+1lp的情况了,也就是分别拿v[minv[2]]v[minv[2]]v[minv[2]]v[p]v[p]v[p]比较,拿u[minu[2]]u[minu[2]]u[minu[2]]u[p]u[p]u[p]比较
  • 以此类推,若比到最后均符合,则h++h++h++minv[h]=minu[h]=pminv[h]=minu[h]=pminv[h]=minu[h]=p
    若对于2≤j≤h2≤j≤h2jh出现v[p]v[p]v[p]<v[minv[j]]v[minv[j]]v[minv[j]]u[p]u[p]u[p]<u[minu[j]]u[minu[j]]u[minu[j]],则将hhh置为jjjminv[h]=minu[h]=pminv[h]=minu[h]=pminv[h]=minu[h]=p
    下面放上代码
#include<stdio.h>
#include<map>
#include<queue>
#include<iostream>
#include<algorithm>
#include<vector>
#define MOD 10000000007
using namespace std;
int a[100005],b[100005];
int a1[100005],b1[100005];
int h,n;
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        h=1;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)scanf("%d",&b[i]);
        a1[h]=b1[h]=1;
        int p;
        for(p=2;p<=n;p++)
        {
        	int j;
        	for(j=1;j<=h;j++)
        	if(a[a1[j]]>a[p]&&b[b1[j]]>b[p])break;
        	else if((a[a1[j]]<a[p]&&b[b1[j]]>b[p])||(a[a1[j]]>a[p]&&b[b1[j]]<b[p])) break;
        	if(j<=h) if((a[a1[j]]<a[p]&&b[b1[j]]>b[p])||(a[a1[j]]>a[p]&&b[b1[j]]<b[p])) break;
        	h=j;a1[h]=b1[h]=p;
        }
        p--;
        printf("%d\n",p);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值