题目大意:等价数组定义为(1≤l≤r≤m)中,所有的子区间都满足最小值下标相等,找出最大的m。
思路:我们枚举下标,如果当前下标i不满足,显然我们就可以结束循环了。那么现在的关键是怎么样去判断下标i是否满足。
①首先我们需要知道每增加一个数,那么多了哪些区间。在枚举的过程中,我们会发现如果对于AB新增一个数C,那么增加的区间则是BC,ABC。显然增加的区间是从当前下标i一直到下标1。这个时候我们知道第二层循环应该就是从i-1一直到1。
②然后我们需要判断当前增加的区间是否满足。
1.区间j到i,最小值下标改变。只有当A,B数组同时改变才满足,其他情况不满足。
2.区间j到i,最小值下标不改变。当前i是满足答案的,我们可以直接结束循环,i++。(解释一下为什么,假设A数组为{a1,b1},B数组为{a2,b2},且j=2,现在A数组新增的数为c1,B数组增加的数为C2,
那么由于最小值不改变,因此c1>b1,c2>b2。如果能枚举到这一步,那么i=2是满足条件的,则此时只有两种情况①b1>a1&&b2>a2②b1<a1&&b2<a2,而无论哪一种情况,都不会改变最小值下标)
#include<iostream> #include<cstring> using namespace std; const int maxn=1e5+10; int a[maxn],b[maxn]; int main() { //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); int n; while(cin>>n) { for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) cin>>b[i]; int ans=n; for(int i=1;i<=n;i++) { bool flag=true; for(int j=i-1;j;j--) { if((a[j]<a[i]&&b[j]>b[i])||(a[j]>a[i]&&b[j]<b[i])) { flag=false; //coutl<<i<<" "<<a[i]<<" "<<a[j]<<" "<<b[i]<<" "<<b[j]<<endl; break; } else if(a[j]<a[i]&&b[j]<b[i])break; } if(!flag) { ans=i-1; break; } } cout<<ans<<endl; } return 0; }