社区讨论

蒟蒻的一点疑问

P4309[TJOI2013] 最长上升子序列参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lojogcm1
此快照首次捕获于
2023/11/04 14:42
2 年前
此快照最后确认于
2023/11/04 16:16
2 年前
查看原帖
上午模拟赛考了这题,但是数据范围开到了 1n1×1061\le n\le1\times10^6,时限开到了 2s2s,那边正解给的是离线线段树,但我写了个这个 Splay 交上去却 T 了,O(nlogn)O(n\log n) 线段树能过 Splay 应该不会过不了吧,难不成写成 Spaly 了(
CPP
#include <bits/stdc++.h>
#define in inline
#define rint register int
#define ls s[0]
#define rs s[1]
#define r(a) compilerror::runtimerror(a)
#define w(a) compilerror::wronganswer(a)
#define wl(a) compilerror::wronganswer(a),compilerror::pc('\n')
#define ws(a) compilerror::wronganswer(a),compilerror::pc(' ')
using namespace std;
typedef long long ll;
namespace compilerror{
    const int pp2=(1<<20)-1;int pp1=-1;
    char buf_in[1<<20],buf_out[1<<20],*p1=buf_in,*p2=buf_in;
    in void flush(){fwrite(buf_out,1,pp1+1,stdout);pp1=-1;}
    in void pc(const char ch){if(pp1==pp2)flush();buf_out[++pp1]=ch;}
    in char gc(){return p1==p2&&(p2=(p1=buf_in)+fread(buf_in,1,1<<20,stdin),p1==p2)?EOF:*p1++;}
    template <typename t> in void runtimerror(t &x){
        char ch=gc();bool f=false;x=0;
        for(;!isdigit(ch);ch=gc()) if(ch=='-') f=true;
        for(;isdigit(ch);ch=gc()) x=(x<<3)+(x<<1)+(ch^48);
        if(f) x=~x+1;
    }
    template <typename t> in void wronganswer(t x){
        if(!x) pc('0');
        else{
            static char stk[20];int top=0;
            if(x<0) pc('-'),x=~x+1;
            while(x) stk[top++]=x%10,x/=10;
            while(top--) pc(stk[top]^48);
        }
    }
}
int n,pos;
struct splay_tree{
    int root,size;
    struct node{
        int s[2],fa,size,maxn,val;
    }tr[1000010];
    in int new_node(int fa,int val){
        int id=++size;
        tr[id].fa=fa,tr[id].val=tr[id].maxn=val;
        return id;
    }
    in void pushup(int id){
        tr[id].size=tr[tr[id].ls].size+tr[tr[id].rs].size+1;
        tr[id].maxn=max(max(tr[id].val,tr[tr[id].ls].maxn),tr[tr[id].rs].maxn);
    }
    in void init(){
        root=new_node(0,0);
        tr[root].rs=new_node(root,0);
        pushup(root);
    }
    in void rotate(int id){
        int fa=tr[id].fa,gr=tr[fa].fa,tos=tr[fa].rs==id;
        tr[gr].s[tr[gr].rs==fa]=id,tr[id].fa=gr;
        tr[fa].s[tos]=tr[id].s[!tos],tr[tr[id].s[!tos]].fa=fa;
        tr[id].s[!tos]=fa,tr[fa].fa=id;
        pushup(fa),pushup(id);
    }
    in void splay(int id,int aim){
        while(tr[id].fa!=aim){
            int fa=tr[id].fa,gr=tr[fa].fa;
            if(gr!=aim){
                if((tr[gr].rs==fa)^(tr[fa].rs==id)) rotate(id);
                else rotate(fa);
            }
            rotate(id);
        }
        if(!aim) root=id;
    }
    int query_id(int id,int rank){
        if(!id) return 0;
        if(tr[tr[id].ls].size>=rank) return query_id(tr[id].ls,rank);
        if(tr[tr[id].ls].size+1==rank){
            splay(id,0);
            return id;
        }
        return query_id(tr[id].rs,rank-tr[tr[id].ls].size-1);
    }
    in void insert(int pos,int val){
        int l=query_id(root,pos+1),r=query_id(root,pos+2);
        splay(r,0),splay(l,r);
        tr[l].rs=new_node(l,val);
        pushup(l),pushup(r);
        splay(tr[l].rs,0);
    }
    in int query(int l,int r){
        l=query_id(root,l),r=query_id(root,r+2);
        splay(r,0),splay(l,r);
        return tr[tr[l].rs].maxn;
    }
    in int getans(){
        return tr[root].maxn;
    }
}t;
int main(){
    #ifndef ONLINE_JUDGE
    freopen("cin.in","r",stdin);
    freopen("cout.out","w",stdout);
    #endif
    r(n);
    t.init();
    for(rint i=1;i<=n;i++){
        r(pos);
        t.insert(pos,t.query(1,pos)+1);
        wl(t.getans());
    }
    compilerror::flush();
    return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...