Splay

適用題目特征

維護區(qū)間翻轉。

原理

想要翻轉區(qū)間[l,r],只要將Splay重構如下。

區(qū)間翻轉

并且在每次操作后,都模仿類似線段樹lazy標記,下傳區(qū)間翻轉標記即可。
PS:Splay實現(xiàn)時,通常需要加入首尾兩個節(jié)點來處理邊界情況,所以最終處理書上相關操作時,都要考慮這個兩個節(jié)點。

例題

Luogu P3391
代碼如下

/*
Luogu P3391
*/
#define method_2
#ifdef method_1
/*

*/

#endif
#ifdef method_2
/*

*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#include<bitset>
#define D(x) cout<<#x<<" = "<<x<<"  "
#define E cout<<endl
#define rep(i,s,t) for(int i=(s);i<=(t);i++)
#define rep0(i,s,t) for(int i=(s);i<(t);i++)
#define rrep(i,t,s) for(int i=(t);i>=(s);i--)
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=100000+5;
const int INF=0x3f3f3f3f;
int n,m;
int a[maxn];
struct Splay{
    int sz,tag,f,son[2],val;
}s[maxn];
int rt;
#define pushup(x) (s[x].sz=s[s[x].son[0]].sz+s[s[x].son[1]].sz+1)
#define rever(x) (swap(s[x].son[0],s[x].son[1]),s[x].tag^=1)
#define pushdown(x) (s[x].tag&&(rever(s[x].son[0]),rever(s[x].son[1]),s[x].tag=0))
#define which(x) (s[s[x].f].son[1]==x)
#define connect(x,y,d) (s[s[x].f=y].son[d]=x)
#define split(x,y) (splay(find(x),rt),splay(find((y)+2),s[rt].son[1]),s[s[rt].son[1]].son[0])
inline void rotate(int x,int& k){
    register int fa=s[x].f,pa=s[fa].f,d=which(x);pushdown(fa),pushdown(x),
    (fa^k?s[pa].son[which(fa)]=x:k=x),s[x].f=pa,connect(s[x].son[d^1],fa,d),connect(fa,x,d^1),pushup(fa),pushup(x);
}
inline void splay(int x,int& k) {int fa;while(x^k) fa=s[x].f,fa^k&&(rotate(which(x)^which(fa)?x:fa,k),0),rotate(x,k);}
inline void build(int l,int r,int& rt){
    int mid=l+r>>1;
    if(s[rt=mid].sz=1,s[rt].val=a[mid],!(l^r)) return;
    l<mid&&(build(l,mid-1,s[rt].son[0]),s[s[rt].son[0]].f=rt),
    r>mid&&(build(mid+1,r,s[rt].son[1]),s[s[rt].son[1]].f=rt),
    pushup(rt);
}
inline int find(int rk){
    int x=rt;
    while(x) {
        if(pushdown(x),s[s[x].son[0]].sz>=rk) x=s[x].son[0];
        else if(!(rk-=s[s[x].son[0]].sz+1)) return x;
        else x=s[x].son[1];
    }
}
inline void reverse(int l,int r){
    int k=split(l,r);rever(k);
}
void dfs(int x){
    pushdown(x);
    if(s[x].son[0]) dfs(s[x].son[0]);
    if(s[x].val!=-INF&&s[x].val!=INF) printf("%d ",s[x].val);
    if(s[x].son[1]) dfs(s[x].son[1]);
}
void solve(){
    build(1,n+2,rt);
    rep(x,2,n+1){
        int l,r;scanf("%d%d",&l,&r);
        reverse(l,r);
    }
    dfs(rt);
}
int main() {
//  ios::sync_with_stdio(false);
//  freopen("文藝平衡樹.in","r",stdin);
    scanf("%d%d",&n,&m);
    a[1]=-INF,a[n+2]=INF;
    int x;
    rep(i,1,n) a[i+1]=i;
    solve();
    return 0;
}
#endif
#ifdef method_3
/*

*/

#endif

Luogu P4402
代碼如下

/*
Luogu P4402 
*/
#define method_1
#ifdef method_1
/*

*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#include<bitset>
#define D(x) cout<<#x<<" = "<<x<<"  "
#define E cout<<endl
#define rep(i,s,t) for(int i=(s);i<=(t);i++)
#define rep0(i,s,t) for(int i=(s);i<(t);i++)
#define rrep(i,t,s) for(int i=(t);i>=(s);i--)
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=100000+5;
const int INF=0x3f3f3f3f;
int n;
struct s{
    int id,val;
    bool operator<(const s &h)const{return val<h.val||(val==h.val&&id<h.id);}
}a[maxn];
struct Splay{
    int sz,tag,f,son[2];
}s[maxn];
int rt;
#define pushup(x) (s[x].sz=s[s[x].son[0]].sz+s[s[x].son[1]].sz+1)
#define rever(x) (swap(s[x].son[0],s[x].son[1]),s[x].tag^=1)
#define pushdown(x) (s[x].tag&&(rever(s[x].son[0]),rever(s[x].son[1]),s[x].tag=0))
#define which(x) (s[s[x].f].son[1]==x)
#define connect(x,y,d) (s[s[x].f=y].son[d]=x)
#define split(x,y) (splay(find(x),rt),splay(find((y)+2),s[rt].son[1]),s[s[rt].son[1]].son[0])
inline void rotate(int x,int& k){
    register int fa=s[x].f,pa=s[fa].f,d=which(x);pushdown(fa),pushdown(x),
    (fa^k?s[pa].son[which(fa)]=x:k=x),s[x].f=pa,connect(s[x].son[d^1],fa,d),connect(fa,x,d^1),pushup(fa),pushup(x);
}
inline void splay(int x,int& k) {int fa;while(x^k) fa=s[x].f,fa^k&&(rotate(which(x)^which(fa)?x:fa,k),0),rotate(x,k);}
inline void build(int l,int r,int& rt){
    int mid=l+r>>1;
    if(s[rt=mid].sz=1,!(l^r)) return;
    l<mid&&(build(l,mid-1,s[rt].son[0]),s[s[rt].son[0]].f=rt),
    r>mid&&(build(mid+1,r,s[rt].son[1]),s[s[rt].son[1]].f=rt),
    pushup(rt);
}
inline int find(int rk){
    int x=rt;
    while(x) {
        if(pushdown(x),s[s[x].son[0]].sz>=rk) x=s[x].son[0];
        else if(!(rk-=s[s[x].son[0]].sz+1)) return x;
        else x=s[x].son[1];
    }
}
inline void reverse(int l,int r){
    int k=split(l,r);rever(k);
}
void solve(){
    sort(a+2,a+n+2);
    build(1,n+2,rt);
    rep(x,2,n+1){
        splay(a[x].id+1,rt);
        int ans=s[s[rt].son[0]].sz;printf("%d ",ans);
        reverse(x-1,ans);
    }
}
int main() {
//  ios::sync_with_stdio(false);
//  freopen("機械排序.in","r",stdin);
    scanf("%d",&n);
    a[1].val=-INF,a[n+2].val=INF;
    a[1].id=-INF,a[n+2].id=INF;
    int x;
    rep(i,1,n) scanf("%d",&x),a[i+1].id=i,a[i+1].val=x;
    solve();
    return 0;
}
#endif
#ifdef method_2
/*

*/

#endif
#ifdef method_3
/*

*/

#endif
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容