Bu Ti: more than 2019 cattle off summer school camp (first)

Game links

Thoroughly pit teammate = =


 

A. Equivalent Prefixes

[Idea] on the examination room

Front to back sweep, the current location of a $ I $, added after determining whether the equivalent, is determined corresponding to $ j = max \ {j \ text {|} a [j] <a [i], j <i \} $, $ k = max \ {k \ text {|} b [k] <b [i], k <i \} $ are equal

This can be binary + segment sloth mark resolved:

Each time interval assigned to a $ a [i], b [i] $ interval corresponding to the segment tree $ [j + 1, i] $ $ I $ are assigned (if assigned, is tacitly $ j = k $ ), the subscript represents the minimum of this interval is the number of $ I $

Then for the new $ i $, you can find half of $ j $, $ k $

Overall complexity $ O (n (logn) ^ 2) $

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=100005;

int n;
int a[N],b[N];

struct SegTree
{
int sz;
int t[N<<2],tag[N<<2];

void Init(int x)
{
    sz=x;
    for(int i=1;i<(sz<<1);i++)
        t[i]=tag[i]=0;
}

inline void Push(int k)
{
    if(!tag[k])
        return;
    
    t[k]=tag[k];
    tag[k]=0;
    if(k>=sz)
        return;
    tag[k<<1]=tag[k<<1|1]=t[k];
}

inline void Add(int k,int l,int r,int a,int b,int x)
{
    Push(k);
    if(a>r || b<l)
        return;
    if(a>=l && b<=r)
    {
        tag[k]=x;
        Push(k);
        return;
    }
    int mid=(a+b)>>1;
    Add(k<<1,l,r,a,mid,x);
    Add(k<<1|1,l,r,mid+1,b,x);
}

inline int Query(int k,int p,int a,int b)
{
    Push(k);
    if(a==b)
        return t[k];
    int mid=(a+b)>>1;
    if(p<=mid)
        return Query(k<<1,p,a,mid);
    else
        return Query(k<<1|1,p,mid+1,b);
}
}ta,tb;

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]);
        
        int sz=1;
        while(sz<n)
            sz<<=1;
        
        ta.Init(sz),tb.Init(sz);
        
        int ans=1;
        ta.Add(1,1,1,1,sz,1);
        tb.Add(1,1,1,1,sz,1);
        for(int i=2;i<=n;i++)
        {
            int pa,pb;
            int left=1,right=i-1,mid;
            while(left<right)
            {
                mid=(left+right)>>1;
                if(a[ta.Query(1,mid,1,sz)]<a[i])
                    left=mid+1;
                else
                    right=mid;
            }
            if(a[left]>a[i])
                left--;
            pa=left;
            
            left=1,right=i-1;
            while(left<right)
            {
                mid=(left+right)>>1;
                if(b[tb.Query(1,mid,1,sz)]<b[i])
                    left=mid+1;
                else
                    right=mid;
            }
            if(b[left]>b[i])
                left--;
            pb=left;
            
            if(pa!=pb)
                break;
            ans=i;
            
            ta.Add(1,pa+1,i,1,sz,i);
            tb.Add(1,pb+1,i,1,sz,i);
        }
        printf("%d\n",ans);
    }
    return 0;
}
View Code

[Normal practice]


 

Guess you like

Origin www.cnblogs.com/LiuRunky/p/Nowcoder_2019_Multischool_Round1.html