A.Equivalent Prefixes

题目大意:等价数组定义为(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;
}

猜你喜欢

转载自www.cnblogs.com/pbzyl999/p/11209553.html
今日推荐