初学splay求助

P3391 【模板】文艺平衡树

_Int_ @ 2021-11-12 09:02:16

爆零蒟蒻,在线卑微求助(虽然一般发求助贴没什么人帮忙TAT

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
inline void in(int &x){
    x=0;int f=1;char c=getchar();
    while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=getchar();
    x*=f;
}
const int N=100005;
int n,m,root,tot;
struct node{
    int fa,ch[2];
    int val,cnt,siz;
    int tag;
}a[N];
void Pushdown(int x){
    if(x&&a[x].tag){
        a[a[x].ch[0]].tag^=1;
        a[a[x].ch[1]].tag^=1;
        a[x].ch[0]^=a[x].ch[1]^=a[x].ch[0]^=a[x].ch[1];
        a[x].tag=0;
    }
}
void Update(int x){
    if(x){
        a[x].siz=a[x].cnt;
        if(a[x].ch[0])a[x].siz+=a[a[x].ch[0]].siz;
        if(a[x].ch[1])a[x].siz+=a[a[x].ch[1]].siz;
    }
}
void Rotate(int x){
    int fath=a[x].fa;
    int graf=a[fath].fa;
    Pushdown(x);
    Pushdown(fath);
    bool flag=(a[fath].ch[1]==x);
    a[graf].ch[a[graf].ch[1]==fath]=x;
    a[x].fa=graf;
    a[fath].ch[flag]=a[x].ch[flag^1];
    a[a[x].ch[flag^1]].fa=fath;
    a[x].ch[flag^1]=fath;
    a[fath].fa=x;
    Update(fath);
    Update(x); 
}
void Splay(int x,int t){
    while(a[x].fa!=t){
        int fath=a[x].fa;
        int graf=a[fath].fa;
        if(graf!=t)
            (a[graf].ch[0]==fath)^(a[fath].ch[0]==x)?Rotate(x):Rotate(fath);
        Rotate(x);
    }
    if(t==0)root=x;
}
void Find(int x){
    int u=root;
    if(!u)return;
    while(a[u].ch[x>a[u].val]&&a[u].val!=x){
        Pushdown(u);
        u=a[u].ch[x>a[u].val];
    }
    Splay(u,0); 
}
void Insert(int x){
    int u=root,fath=0;
    while(u&&a[u].val!=x){
        fath=u;
        u=a[u].ch[x>a[u].val];
    }
    if(u){
        a[u].cnt++;
        Update(u);
        Update(fath);
        Splay(u,0);
        return;
    }
    u=++tot;
    if(fath)
        a[fath].ch[x>a[fath].val]=u;
    a[u].ch[0]=a[u].ch[1]=0;
    a[u].fa=fath;
    a[u].val=x;
    a[u].cnt=1;
    a[u].siz=1;
    Splay(u,0);
}
int Find_pre_next(int x,int flag){
    Find(x);
    int u=root;
    if((a[u].val>x&&flag)||(a[u].val<x&&!flag))return u;
    u=a[u].ch[flag];
    while(a[u].ch[flag^1])
        u=a[u].ch[flag^1];
    return u;
}
void Delete(int x){
    int last=Find_pre_next(x,0);
    int next=Find_pre_next(x,1);
    Splay(last,0);
    Splay(next,last);
    int del=a[next].ch[0];
    if(a[del].cnt>1){
        a[del].cnt--;
        Splay(del,0);
    }
    else
        a[next].ch[0]=0;
}
int Find_rank(int x){
    int u=root,rnk=1;
    while(a[u].val!=x){
        if(x<a[u].val){
            u=a[u].ch[0];
            continue;
        }
        rnk+=a[a[u].ch[0]].siz+a[u].cnt;
        u=a[u].ch[1];
    }
    rnk+=a[a[u].ch[0]].siz;
    Splay(u,0);
    return rnk;
}
int Find_kth(int x){
    int u=root;
    if(a[u].siz<x||x<0)
        return 0;
    while(1){
        if(x>a[a[x].ch[0]].siz+a[u].cnt){
            x-=a[a[u].ch[0]].siz+a[u].cnt;
            u=a[u].ch[1];
        }
        else if(a[a[u].ch[0]].siz>=x)u=a[u].ch[0];
        else return a[u].val;
    }
}
void Reverse(int l,int r){
    int x=Find_kth(l),y=Find_kth(r+2);
    Splay(x,0);
    Splay(y,x);
    a[a[y].ch[0]].tag^=1;
}
void Output(int x){
    Pushdown(x);
    if(a[x].ch[0])Output(a[x].ch[0]);
    if(a[x].val>1&&a[x].val<n+2)printf("%d ",a[x].val-1);
    if(a[x].ch[1])Output(a[x].ch[1]);
}
int main(){
    in(n);in(m);
    for(int i=1;i<=n+2;i++)
        Insert(i); 
    while(m--){
        int l,r;
        in(l);in(r);
        Reverse(l,r); 
    }
    Output(root);
    return 0;
} 

by Mr_H2T @ 2021-11-12 09:04:07

这个 splay 找人调有些困难吧


by loris @ 2021-11-12 09:37:06

如果代码短就会有人看,建议把觉得有问题的地方单独拿出来,发帖求助。


by K0stlin @ 2021-11-12 11:35:14

sto xsy orz


by _Int_ @ 2021-11-12 21:31:53

@Mr_H2T 自己慢慢看吧TAT


by _Int_ @ 2021-11-12 22:45:27

@Mr_H2T 谢谢dalao,打错一个字母QwQ,此贴终


by K_srh @ 2022-07-21 00:04:50

@Int

哪里打错了


|