제출 #1362118

#제출 시각아이디문제언어결과실행 시간메모리
1362118Aviansh서열 (APIO23_sequence)C++20
100 / 100
689 ms56348 KiB
#include "sequence.h"

#include <bits/stdc++.h>

using namespace std;

const int inf = 1e9;

struct segTree{
    //treat 0 as +-1, rest are either +1 or -1 fixed.
    //store prefmin, prefmax, summin, summax, sufmin, sufmax
    struct node{
        int prefmin, prefmax, summin, summax, sufmin, sufmax;
    };
    node unite(node a, node b){
        node ans;
        ans.prefmin = min(a.prefmin,a.summin+b.prefmin);
        ans.prefmax = max(a.prefmax,a.summax+b.prefmax);
        ans.summin = a.summin+b.summin;
        ans.summax = a.summax+b.summax;
        ans.sufmin = min(b.sufmin,b.summin+a.sufmin);
        ans.sufmax = max(b.sufmax,b.summax+a.sufmax);
        return ans;
    }
    node *st;
    node def;
    void build(int l, int r, int ind){
        if(l==r){
            st[ind].summin=1;
            st[ind].summax=1;
            st[ind].prefmin=1;
            st[ind].prefmax=1;
            st[ind].sufmin=1;
            st[ind].sufmax=1;
            return;
        }
        int mid = (l+r)/2;
        build(l,mid,ind*2+1);
        build(mid+1,r,ind*2+2);
        st[ind]=unite(st[ind*2+1],st[ind*2+2]);
    }
    int n;
    segTree(int siz){
        n=siz;
        int x = ceil(log2(n));
        x++;
        st=new node[(1<<x)];
        def.prefmin=inf;
        def.sufmin=inf;
        def.summin=0;
        def.prefmax=-inf;
        def.sufmax=-inf;
        def.summax=0;
        ///initialize with 0s
        build(0,n-1,0);
    }
    void update(int i, int val, int l=0, int r=-1, int ind=0){
        if(r==-1)
            r=n-1;
        if(i<l||i>r)
            return;
        if(l==r){
            if(val==0){
                st[ind].summin=-1;
                st[ind].summax=1;
                st[ind].prefmin=-1;
                st[ind].prefmax=1;
                st[ind].sufmin=-1;
                st[ind].sufmax=1;
            }
            else if(val==1){
                st[ind].summin=1;
                st[ind].summax=1;
                st[ind].prefmin=1;
                st[ind].prefmax=1;
                st[ind].sufmin=1;
                st[ind].sufmax=1;
            }
            else if(val==-1){
                st[ind].summin=-1;
                st[ind].summax=-1;
                st[ind].prefmin=-1;
                st[ind].prefmax=-1;
                st[ind].sufmin=-1;
                st[ind].sufmax=-1;
            }
            else{
                assert(0);
            }
            return;
        }
        int mid = (l+r)/2;
        update(i,val,l,mid,ind*2+1);
        update(i,val,mid+1,r,ind*2+2);
        st[ind]=unite(st[ind*2+1],st[ind*2+2]);
    }
    node query(int s, int e, int l=0, int r=-1, int ind=0){
        if(r==-1)
            r=n-1;
        if(e<l||s>r){
            return def;
        }
        if(s<=l&&r<=e){
            return st[ind];
        }
        int mid = (l+r)/2;
        return unite(query(s,e,l,mid,ind*2+1),query(s,e,mid+1,r,ind*2+2));
    }
};

int sequence(int n, vector<int> arr) {
    vector<int>pos[n];
    for(int i = 0;i<n;i++){
        arr[i]--;
        pos[arr[i]].push_back(i);
    }
    segTree st(n);
    int ans = 1;
    for(int elem = 0;elem<n;elem++){
        //set this elem to 0
        for(int j : pos[elem]){
            st.update(j,0);
        }
        int l = 0;
        for(int r = 0;r<pos[elem].size();r++){
            //check validity
            segTree::node lef = st.query(0,pos[elem][l]);
            segTree::node rig = st.query(pos[elem][r],n-1);
            segTree::node mid = st.query(pos[elem][l],pos[elem][r]);
            while(!(lef.sufmin+rig.prefmin+mid.summin+1+1<=0&&lef.sufmax+rig.prefmax+mid.summax-1-1>=0)){
                //invalid
                l++;
                lef = st.query(0,pos[elem][l]);
                rig = st.query(pos[elem][r],n-1);
                mid = st.query(pos[elem][l],pos[elem][r]);
            }
            ans=max(ans,(r-l+1));
            if(lef.sufmin+rig.prefmin+mid.summin+1+1<=0&&lef.sufmax+rig.prefmax+mid.summax-1-1>=0){
                ///this is valid
            }
            else{
                assert(0);
            }
        }
        for(int j : pos[elem]){
            st.update(j,-1);
        }
    }
    return ans;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…