UOJ#31. 【UR #2】猪猪侠再战括号序列 splay

显然可以直接凑左面全是左括号,右面全是右括号的情况.   

然后区间翻转就用 splay 模拟好了.  

splay 的时候一定注意一点:  

如果没有调用 find(x),就一定要手动把 x 及其祖先的节点 pushdown. 

code; 

#include <bits/stdc++.h>     
#define N 100009   
#define ll long long  
#define lson s[x].ch[0] 
#define rson s[x].ch[1] 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;
char str[N<<1];  
int n,tot,root,A[N<<1],sta[N<<1];   
struct node { 
    int ch[2],rev,f,w,pos,si;          
}s[N<<1];            
int get(int x) { return s[s[x].f].ch[1]==x; }           
void mark(int x) 
{
    swap(lson,rson),s[x].rev^=1;             
}   
void pushup(int x) 
{
    int l=lson,r=rson;   
    s[x].si=s[l].si+s[r].si+1;                                          
    if(s[x].w==1) s[x].pos=x;   
    else s[x].pos=0;              
    if(s[l].pos)  s[x].pos=s[l].pos;             
    if(s[r].pos)  s[x].pos=s[r].pos;                   
}    
void pushdown(int x) 
{      
    if(s[x].rev) {
        if(lson) mark(lson); 
        if(rson) mark(rson);  
        s[x].rev=0;  
    }
}   
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);  
}   
void splay(int x,int &tar) 
{
    int fa,u=x,v=0; 
    for(sta[++v]=u;u!=tar;u=s[u].f) sta[++v]=s[u].f;              
    for(;v;--v) pushdown(sta[v]);   
    for(u=s[u].f;(fa=s[x].f)!=u;rotate(x))  
        if(s[fa].f!=u) rotate(get(fa)==get(x)?fa:x);   
    tar=x;  
}         
int find(int x,int kth) 
{                         
    pushdown(x);   
    if(s[lson].si+1==kth) return x;   
    else
    {
        if(s[lson].si>=kth) return find(lson,kth);   
        else return find(rson,kth-s[lson].si-1);  
    }  
}       
int build(int l,int r,int ff) 
{     
    int mid=(l+r)>>1;  
    int cur=++tot;    
    s[cur].f=ff;   
    s[cur].w=A[mid];       
    if(mid>l) s[cur].ch[0]=build(l,mid-1,cur);   
    if(r>mid) s[cur].ch[1]=build(mid+1,r,cur);    
    pushup(cur);   
    return cur;  
}            
int cnt;  
int tl[N],tr[N];   
int main() 
{ 
    // setIO("input");
    scanf("%s",str+1),n=strlen(str+1);   
    for(int i=1;i<=n;++i) A[i]=(str[i]=='('?1:-1);
    root=build(0,n+1,0);                 
    for(int i=1;i<=n/2;++i) 
    {        
        int CUR;        
        splay(CUR=find(root,i+1),root);                                  
        if(s[root].w==1) continue;     
        else{                                  
            int PRE=find(root,i);            
            splay(PRE,root);     
            int z=s[s[PRE].ch[1]].pos;      
            splay(z,root);      
            int k=s[s[z].ch[0]].si+1;   
            splay(PRE,root);       
            splay(find(root,k+1),s[PRE].ch[1]);    
            int tmp=s[s[PRE].ch[1]].ch[0];    
            mark(tmp);  
            ++cnt;   
            tl[cnt]=i,tr[cnt]=k-1;  
        }
    }
    printf("%d
",cnt);        
    for(int i=1;i<=cnt;++i) printf("%d %d
",tl[i],tr[i]);      
    return 0; 
}

  

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