题意:求最大的q使得 两个区间{a1,a2,…,ap},对于任意的1≤l≤r≤m的rmq下标相等
题解:二分查找p的最大值,然后对于每一个区间首先查询两个区间最小值的下标相等,然后如果相等递归看去掉当前最小值的左右区间是否继续符合
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5+10, INF = 0x3f3f3f3f; #define mod 998244353 #define pi acos(-1.0) int a[maxn],b[maxn],vis1[maxn],vis2[maxn]; int n; int dp1[maxn][25],dp2[maxn][25]; void rmq_init(){ for(int i=1;i<=n;i++) dp1[i][0]=a[i],dp2[i][0]=b[i]; for(int j=1;(1<<j)<=n;j++){ for(int i=1;i+(1<<j)-1<=n;i++){ dp1[i][j]=min(dp1[i][j-1],dp1[i+(1<<j-1)][j-1]); dp2[i][j]=min(dp2[i][j-1],dp2[i+(1<<j-1)][j-1]); } } } int rmq1(int l,int r){ int k=log2(r-l+1); return min(dp1[l][k],dp1[r-(1<<k)+1][k]); } int rmq2(int l,int r){ int k=log2(r-l+1); return min(dp2[l][k],dp2[r-(1<<k)+1][k]); } int check(int l,int r){ if(l>=r)return 1; else { int t1=vis1[rmq1(l,r)],t2=vis2[rmq2(l,r)]; if(t1==t2&&check(l,t1-1)&&check(t1+1,r)) return 1; } return 0; } int main() { while(scanf("%d",&n)!=EOF){ for(int i=1;i<=n;i++){ scanf("%d",&a[i]); vis1[a[i]]=i; } for(int i=1;i<=n;i++){ scanf("%d",&b[i]); vis2[b[i]]=i; } rmq_init(); int l=1,r=n; int ans=0; while(l<=r){ int mid=(l+r)/2; //cout<<mid<<endl; if(check(1,mid)){ l=mid+1; ans=mid; }else r=mid-1; } cout<<ans<<endl; } }