CF809D Hitchhiking in the Baltic States 平衡树(Splay)

维护 $dp[i]$ 表示长度为 $i$ 的 $LIS$ 的最小结尾长度.      

然后每次我们新加入一个区间 $[l,r]$ ,这个可以用平衡树来维护:区间平移,区间+1,单点赋值. 

调不出来QAQ....

code:

#include <cstdio>   
#include <string>
#include <cstring>
#include <algorithm>    
#define ll long long 
#define N 300007     
#define MAX 1200000000   
#define lson s[x].ch[0] 
#define rson s[x].ch[1]   
#define setIO(s) freopen(s".in","r",stdin)    
using namespace std;   
struct node 
{      
    int ch[2],f,v,tag,siz;    
    node() { ch[0]=ch[1]=f=v=tag=siz=0;}    
}s[N];  
int tot,root,ans;       
int newnode() { return ++tot; }    
inline void pushup(int x) 
{ 
    s[x].siz=s[lson].siz+s[rson].siz+1; 
}  
inline int get(int x) 
{ 
    return s[s[x].f].ch[1]==x; 
}   
inline void mark(int x,int v) 
{ 
    s[x].v+=v,s[x].tag+=v; 
}
inline void pushdown(int x) 
{
    if(s[x].tag) 
    {
        if(lson) 
            mark(lson,s[x].tag);   
        if(rson) 
            mark(rson,s[x].tag); 
        s[x].tag=0;  
    }
}  
inline void rotate(int x) 
{
    int old=s[x].f,fold=s[old].f,which=get(x);  
    s[old].ch[which]=s[x].ch[which^1];  
    if(s[old].ch[which]) 
        s[s[old].ch[which]].f=old;  
    s[x].ch[which^1]=old,s[old].f=x,s[x].f=fold;   
    if(fold) 
        s[fold].ch[s[fold].ch[1]==old]=x;   
    pushup(old),pushup(x);  
}
inline void splay(int x,int &tar) 
{
    int u=s[tar].f;  
    for(int fa;(fa=s[x].f)!=u;rotate(x))  
        if(s[fa].f!=u) 
            rotate(get(fa)==get(x)?fa:x);   
    tar=x;   
}             
void insert(int val) 
{ 
    int x=root,ff=0,d=0;       
    while(x) 
    {      
        ff=x;  
        pushdown(x);   
        if(s[x].v<=val)     
            x=rson,d=1;       
        else 
            x=lson,d=0;     
    } 
    int now=newnode();  
    s[now].v=val,s[now].siz=1,s[now].f=ff;  
    if(ff) s[ff].ch[d]=now,pushup(ff);                               
    splay(now,root);   
}    
int find(int val) 
{
    // 第一个 小于 val 的    
    int x=root,an=0;  
    while(x) 
    {
        pushdown(x);   
        if(s[x].v<val)   
            an=x,x=rson;   
        else x=lson;     
    }
    return an;  
}              
int get_pre(int x) 
{    
    splay(x,root),x=lson;   
    while(rson)  pushdown(x),x=rson;       
    return x;  
}       
int get_nxt(int x) 
{ 
    splay(x,root),x=rson;   
    while(lson)  pushdown(x),x=lson;   
    return x;  
}       
void Delete(int x) 
{
    splay(x,root);   
    int L=s[x].ch[0],R=s[x].ch[1];    
    while(s[L].ch[1]) pushdown(L),L=s[L].ch[1];   
    splay(L,s[x].ch[0]);       
    s[L].f=0;   
    s[L].ch[1]=R,s[R].f=L,pushup(L),root=L; 
    s[x].ch[0]=s[x].ch[1]=s[x].f=0;    
}
void solve(int l,int r) 
{
    int u=find(l),v=find(r),nt=get_nxt(v);    
    if(u!=v) 
    {
        splay(u,root),splay(nt,s[u].ch[1]);     
        int now=s[nt].ch[0];   
        if(now) mark(now,1);                  
    }    
    if(nt!=2)  Delete(nt),--ans;   
    insert(l),++ans;   
}  
/*   
void Solve(int l,int r)
{     
    int u=Find(l),v=Find(r),nt=Getnxt(v);
    if(u^v)
    {
        Splay(u,0);Splay(nt,u);
        int QwQ=t[nt].ch[0];
        t[QwQ].v+=1;t[QwQ].tag+=1;
    }
    if(nt!=2)Delete(nt),--ans;
    Insert(l),++ans;
}
 */
int main() 
{
    // setIO("input");  
    int i,j,Q;  
    insert(-MAX),insert(MAX);      
    scanf("%d",&Q);  
    for(i=1;i<=Q;++i) 
    {
        int l,r;  
        scanf("%d%d",&l,&r),solve(l,r);  
    }
    printf("%d
",ans);   
    return 0;
}

  

原文地址:https://www.cnblogs.com/guangheli/p/12398833.html